Skip to content

Commit 4084c2b

Browse files
authored
Merge branch 'main' into ConstExprFlatCast
2 parents 8a03b0d + d12ab44 commit 4084c2b

File tree

186 files changed

+15423
-1278
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

186 files changed

+15423
-1278
lines changed

.github/workflows/containers/github-action-ci-windows/Dockerfile

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,45 @@ RUN powershell -Command \
9898
Add-Type -AssemblyName System.IO.Compression.FileSystem ; \
9999
[System.IO.Compression.ZipFile]::ExtractToDirectory('actions-runner-win.zip', $PWD) ;\
100100
rm actions-runner-win.zip
101+
102+
# Set the LLVM_VERSION environment variable
103+
ENV LLVM_VERSION=21.1.2
104+
105+
# Download and extract Clang compiler.
106+
# Create directories, download, extract, and clean up all in one layer
107+
RUN powershell -Command \
108+
# --- Setup directories --- \
109+
Write-Host "Creating directories..."; \
110+
New-Item -Path "C:\temp-download" -ItemType "Directory" -Force ; \
111+
New-Item -Path "C:\xz-utils" -ItemType "Directory" -Force ; \
112+
New-Item -Path "C:\clang" -ItemType "Directory" -Force ; \
113+
# --- 1. Download and extract xz --- \
114+
Set-Location C:\temp-download ; \
115+
Invoke-WebRequest -Uri "http://github.com/tukaani-project/xz/releases/download/v5.8.1/xz-5.8.1-windows.zip" -OutFile "xz.zip"; \
116+
(Get-FileHash -Path "C:\temp-download\xz.zip" -Algorithm MD5).Hash -eq 'c3c69fdce3e825cc0b76123b36b0bcc2' ; \
117+
Add-Type -AssemblyName "System.IO.Compression.FileSystem"; \
118+
[System.IO.Compression.ZipFile]::ExtractToDirectory('C:\temp-download\xz.zip', 'C:\xz-utils'); \
119+
# --- 2. Download and decompress Clang --- \
120+
Invoke-WebRequest -Uri "http://github.com/llvm/llvm-project/releases/download/llvmorg-21.1.2/clang+llvm-21.1.2-x86_64-pc-windows-msvc.tar.xz" -OutFile "clang+llvm-21.1.2-x86_64-pc-windows-msvc.tar.xz" ; \
121+
(Get-FileHash -Path "C:\temp-download\clang+llvm-21.1.2-x86_64-pc-windows-msvc.tar.xz" -Algorithm MD5).Hash -eq '0ae1d3effd9ab9d323f7fa595777f0a2' ; \
122+
C:\xz-utils\bin_x86-64\xz.exe -d -qq clang+llvm-21.1.2-x86_64-pc-windows-msvc.tar.xz ; \
123+
# --- 3. Extract clang --- \
124+
C:\Windows\System32\tar.exe -xf clang+llvm-21.1.2-x86_64-pc-windows-msvc.tar -C C:\clang ; \
125+
# --- 4. Clean up --- \
126+
Set-Location C:\ ; \
127+
Remove-Item C:\temp-download -Recurse -Force; \
128+
Remove-Item C:\xz-utils -Recurse -Force; \
129+
# -- 5. Shorten path to clang files & remove unnecessary files -- \
130+
Set-Location C:\clang ; \
131+
Rename-Item -Path "C:\clang\clang+llvm-21.1.2-x86_64-pc-windows-msvc" -NewName "C:\clang\clang-msvc" ; \
132+
Set-Location C:\clang\clang-msvc ; \
133+
Remove-Item -Path C:\clang\clang-msvc\libexec -Recurse -Force ; \
134+
Remove-Item -Path C:\clang\clang-msvc\share -Recurse -Force ; \
135+
Rename-Item -Path "C:\clang\clang-msvc\bin" -NewName "C:\clang\clang-msvc\bin-full" ; \
136+
New-Item -Path "C:\clang\clang-msvc\bin" -ItemType Directory -Force ; \
137+
Set-Location C:\clang\clang-msvc\bin ; \
138+
Copy-Item -Path C:\clang\clang-msvc\bin-full\*.dll -Destination C:\clang\clang-msvc\bin\. ; \
139+
Copy-Item -Path C:\clang\clang-msvc\bin-full\clang-cl.exe -Destination C:\clang\clang-msvc\bin\. ; \
140+
Copy-Item -Path C:\clang\clang-msvc\bin-full\lld-link.exe -Destination C:\clang\clang-msvc\bin\. ; \
141+
Set-Location C:\clang\clang-msvc ; \
142+
Remove-Item -Path C:\clang\clang-msvc\bin-full -Recurse -Force ;

clang-tools-extra/clang-include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ namespace find_all_symbols {
1313

1414
const HeaderMapCollector::RegexHeaderMap *getSTLPostfixHeaderMap() {
1515
static const HeaderMapCollector::RegexHeaderMap STLPostfixHeaderMap = {
16+
{"include/__float_float.h$", "<cfloat>"},
17+
{"include/__float_header_macro.h$", "<cfloat>"},
18+
{"include/__float_infinity_nan.h$", "<cfloat>"},
1619
{"include/__stdarg___gnuc_va_list.h$", "<cstdarg>"},
1720
{"include/__stdarg___va_copy.h$", "<cstdarg>"},
1821
{"include/__stdarg_header_macro.h$", "<cstdarg>"},

clang-tools-extra/clangd/index/CanonicalIncludes.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ namespace clang {
1616
namespace clangd {
1717
namespace {
1818
const std::pair<llvm::StringRef, llvm::StringRef> IncludeMappings[] = {
19+
{"include/__float_float.h", "<cfloat>"},
20+
{"include/__float_header_macro.h", "<cfloat>"},
21+
{"include/__float_infinity_nan.h", "<cfloat>"},
1922
{"include/__stdarg___gnuc_va_list.h", "<cstdarg>"},
2023
{"include/__stdarg___va_copy.h", "<cstdarg>"},
2124
{"include/__stdarg_header_macro.h", "<cstdarg>"},

clang/include/clang/Basic/DiagnosticASTKinds.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,12 @@ def note_constexpr_assumption_failed : Note<
403403
def note_constexpr_countzeroes_zero : Note<
404404
"evaluation of %select{__builtin_elementwise_clzg|__builtin_elementwise_ctzg}0 "
405405
"with a zero value is undefined">;
406+
def note_constexpr_infer_alloc_token_type_inference_failed : Note<
407+
"could not infer allocation type for __builtin_infer_alloc_token">;
408+
def note_constexpr_infer_alloc_token_no_metadata : Note<
409+
"could not get token metadata for inferred type">;
410+
def note_constexpr_infer_alloc_token_stateful_mode : Note<
411+
"stateful alloc token mode not supported in constexpr">;
406412
def err_experimental_clang_interp_failed : Error<
407413
"the experimental clang interpreter failed to evaluate an expression">;
408414

clang/lib/AST/ASTContext.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1648,6 +1648,9 @@ ASTContext::findPointerAuthContent(QualType T) const {
16481648
if (!RD)
16491649
return PointerAuthContent::None;
16501650

1651+
if (RD->isInvalidDecl())
1652+
return PointerAuthContent::None;
1653+
16511654
if (auto Existing = RecordContainsAddressDiscriminatedPointerAuth.find(RD);
16521655
Existing != RecordContainsAddressDiscriminatedPointerAuth.end())
16531656
return Existing->second;
@@ -3517,7 +3520,6 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
35173520
uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) {
35183521
assert(!T->isDependentType() &&
35193522
"cannot compute type discriminator of a dependent type");
3520-
35213523
SmallString<256> Str;
35223524
llvm::raw_svector_ostream Out(Str);
35233525

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
1212
#include "InterpHelpers.h"
1313
#include "PrimType.h"
1414
#include "Program.h"
15+
#include "clang/AST/InferAlloc.h"
1516
#include "clang/AST/OSLog.h"
1617
#include "clang/AST/RecordLayout.h"
1718
#include "clang/Basic/Builtins.h"
1819
#include "clang/Basic/TargetBuiltins.h"
1920
#include "clang/Basic/TargetInfo.h"
2021
#include "llvm/ADT/StringExtras.h"
22+
#include "llvm/Support/AllocToken.h"
2123
#include "llvm/Support/ErrorHandling.h"
2224
#include "llvm/Support/SipHash.h"
2325

@@ -1307,6 +1309,45 @@ interp__builtin_ptrauth_string_discriminator(InterpState &S, CodePtr OpPC,
13071309
return true;
13081310
}
13091311

1312+
static bool interp__builtin_infer_alloc_token(InterpState &S, CodePtr OpPC,
1313+
const InterpFrame *Frame,
1314+
const CallExpr *Call) {
1315+
const ASTContext &ASTCtx = S.getASTContext();
1316+
uint64_t BitWidth = ASTCtx.getTypeSize(ASTCtx.getSizeType());
1317+
auto Mode =
1318+
ASTCtx.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
1319+
uint64_t MaxTokens =
1320+
ASTCtx.getLangOpts().AllocTokenMax.value_or(~0ULL >> (64 - BitWidth));
1321+
1322+
// We do not read any of the arguments; discard them.
1323+
for (int I = Call->getNumArgs() - 1; I >= 0; --I)
1324+
discard(S.Stk, *S.getContext().classify(Call->getArg(I)));
1325+
1326+
// Note: Type inference from a surrounding cast is not supported in
1327+
// constexpr evaluation.
1328+
QualType AllocType = infer_alloc::inferPossibleType(Call, ASTCtx, nullptr);
1329+
if (AllocType.isNull()) {
1330+
S.CCEDiag(Call,
1331+
diag::note_constexpr_infer_alloc_token_type_inference_failed);
1332+
return false;
1333+
}
1334+
1335+
auto ATMD = infer_alloc::getAllocTokenMetadata(AllocType, ASTCtx);
1336+
if (!ATMD) {
1337+
S.CCEDiag(Call, diag::note_constexpr_infer_alloc_token_no_metadata);
1338+
return false;
1339+
}
1340+
1341+
auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
1342+
if (!MaybeToken) {
1343+
S.CCEDiag(Call, diag::note_constexpr_infer_alloc_token_stateful_mode);
1344+
return false;
1345+
}
1346+
1347+
pushInteger(S, llvm::APInt(BitWidth, *MaybeToken), ASTCtx.getSizeType());
1348+
return true;
1349+
}
1350+
13101351
static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC,
13111352
const InterpFrame *Frame,
13121353
const CallExpr *Call) {
@@ -3694,6 +3735,9 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
36943735
case Builtin::BI__builtin_ptrauth_string_discriminator:
36953736
return interp__builtin_ptrauth_string_discriminator(S, OpPC, Frame, Call);
36963737

3738+
case Builtin::BI__builtin_infer_alloc_token:
3739+
return interp__builtin_infer_alloc_token(S, OpPC, Frame, Call);
3740+
36973741
case Builtin::BI__noop:
36983742
pushInteger(S, 0, Call->getType());
36993743
return true;

clang/lib/AST/ExprConstant.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "clang/AST/CharUnits.h"
4545
#include "clang/AST/CurrentSourceLocExprScope.h"
4646
#include "clang/AST/Expr.h"
47+
#include "clang/AST/InferAlloc.h"
4748
#include "clang/AST/OSLog.h"
4849
#include "clang/AST/OptionalDiagnostic.h"
4950
#include "clang/AST/RecordLayout.h"
@@ -15184,6 +15185,27 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1518415185
return Success(Result, E);
1518515186
}
1518615187

15188+
case Builtin::BI__builtin_infer_alloc_token: {
15189+
// If we fail to infer a type, this fails to be a constant expression; this
15190+
// can be checked with __builtin_constant_p(...).
15191+
QualType AllocType = infer_alloc::inferPossibleType(E, Info.Ctx, nullptr);
15192+
if (AllocType.isNull())
15193+
return Error(
15194+
E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
15195+
auto ATMD = infer_alloc::getAllocTokenMetadata(AllocType, Info.Ctx);
15196+
if (!ATMD)
15197+
return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
15198+
auto Mode =
15199+
Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
15200+
uint64_t BitWidth = Info.Ctx.getTypeSize(Info.Ctx.getSizeType());
15201+
uint64_t MaxTokens =
15202+
Info.getLangOpts().AllocTokenMax.value_or(~0ULL >> (64 - BitWidth));
15203+
auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
15204+
if (!MaybeToken)
15205+
return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
15206+
return Success(llvm::APInt(BitWidth, *MaybeToken), E);
15207+
}
15208+
1518715209
case Builtin::BI__builtin_ffs:
1518815210
case Builtin::BI__builtin_ffsl:
1518915211
case Builtin::BI__builtin_ffsll: {

clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,15 @@ static auto isNotOkStatusCall() {
168168
"::absl::UnimplementedError", "::absl::UnknownError"))));
169169
}
170170

171+
static auto isPointerComparisonOperatorCall(std::string operator_name) {
172+
using namespace ::clang::ast_matchers; // NOLINT: Too many names
173+
return binaryOperator(hasOperatorName(operator_name),
174+
hasLHS(hasType(hasCanonicalType(pointerType(
175+
pointee(anyOf(statusOrType(), statusType())))))),
176+
hasRHS(hasType(hasCanonicalType(pointerType(
177+
pointee(anyOf(statusOrType(), statusType())))))));
178+
}
179+
171180
static auto
172181
buildDiagnoseMatchSwitch(const UncheckedStatusOrAccessModelOptions &Options) {
173182
return CFGMatchSwitchBuilder<const Environment,
@@ -438,6 +447,58 @@ static void transferComparisonOperator(const CXXOperatorCallExpr *Expr,
438447
State.Env.setValue(*Expr, *LhsAndRhsVal);
439448
}
440449

450+
static RecordStorageLocation *getPointeeLocation(const Expr &Expr,
451+
Environment &Env) {
452+
if (auto *PointerVal = Env.get<PointerValue>(Expr))
453+
return dyn_cast<RecordStorageLocation>(&PointerVal->getPointeeLoc());
454+
return nullptr;
455+
}
456+
457+
static BoolValue *evaluatePointerEquality(const Expr *LhsExpr,
458+
const Expr *RhsExpr,
459+
Environment &Env) {
460+
assert(LhsExpr->getType()->isPointerType());
461+
assert(RhsExpr->getType()->isPointerType());
462+
RecordStorageLocation *LhsStatusLoc = nullptr;
463+
RecordStorageLocation *RhsStatusLoc = nullptr;
464+
if (isStatusOrType(LhsExpr->getType()->getPointeeType()) &&
465+
isStatusOrType(RhsExpr->getType()->getPointeeType())) {
466+
auto *LhsStatusOrLoc = getPointeeLocation(*LhsExpr, Env);
467+
auto *RhsStatusOrLoc = getPointeeLocation(*RhsExpr, Env);
468+
if (LhsStatusOrLoc == nullptr || RhsStatusOrLoc == nullptr)
469+
return nullptr;
470+
LhsStatusLoc = &locForStatus(*LhsStatusOrLoc);
471+
RhsStatusLoc = &locForStatus(*RhsStatusOrLoc);
472+
} else if (isStatusType(LhsExpr->getType()->getPointeeType()) &&
473+
isStatusType(RhsExpr->getType()->getPointeeType())) {
474+
LhsStatusLoc = getPointeeLocation(*LhsExpr, Env);
475+
RhsStatusLoc = getPointeeLocation(*RhsExpr, Env);
476+
}
477+
if (LhsStatusLoc == nullptr || RhsStatusLoc == nullptr)
478+
return nullptr;
479+
auto &LhsOkVal = valForOk(*LhsStatusLoc, Env);
480+
auto &RhsOkVal = valForOk(*RhsStatusLoc, Env);
481+
auto &Res = Env.makeAtomicBoolValue();
482+
auto &A = Env.arena();
483+
Env.assume(A.makeImplies(
484+
Res.formula(), A.makeEquals(LhsOkVal.formula(), RhsOkVal.formula())));
485+
return &Res;
486+
}
487+
488+
static void transferPointerComparisonOperator(const BinaryOperator *Expr,
489+
LatticeTransferState &State,
490+
bool IsNegative) {
491+
auto *LhsAndRhsVal =
492+
evaluatePointerEquality(Expr->getLHS(), Expr->getRHS(), State.Env);
493+
if (LhsAndRhsVal == nullptr)
494+
return;
495+
496+
if (IsNegative)
497+
State.Env.setValue(*Expr, State.Env.makeNot(*LhsAndRhsVal));
498+
else
499+
State.Env.setValue(*Expr, *LhsAndRhsVal);
500+
}
501+
441502
static void transferOkStatusCall(const CallExpr *Expr,
442503
const MatchFinder::MatchResult &,
443504
LatticeTransferState &State) {
@@ -455,6 +516,18 @@ static void transferNotOkStatusCall(const CallExpr *Expr,
455516
State.Env.assume(A.makeNot(OkVal.formula()));
456517
}
457518

519+
static void transferEmplaceCall(const CXXMemberCallExpr *Expr,
520+
const MatchFinder::MatchResult &,
521+
LatticeTransferState &State) {
522+
RecordStorageLocation *StatusOrLoc =
523+
getImplicitObjectLocation(*Expr, State.Env);
524+
if (StatusOrLoc == nullptr)
525+
return;
526+
527+
auto &OkVal = valForOk(locForStatus(*StatusOrLoc), State.Env);
528+
State.Env.assume(OkVal.formula());
529+
}
530+
458531
CFGMatchSwitch<LatticeTransferState>
459532
buildTransferMatchSwitch(ASTContext &Ctx,
460533
CFGMatchSwitchBuilder<LatticeTransferState> Builder) {
@@ -482,8 +555,24 @@ buildTransferMatchSwitch(ASTContext &Ctx,
482555
transferComparisonOperator(Expr, State,
483556
/*IsNegative=*/true);
484557
})
558+
.CaseOfCFGStmt<BinaryOperator>(
559+
isPointerComparisonOperatorCall("=="),
560+
[](const BinaryOperator *Expr, const MatchFinder::MatchResult &,
561+
LatticeTransferState &State) {
562+
transferPointerComparisonOperator(Expr, State,
563+
/*IsNegative=*/false);
564+
})
565+
.CaseOfCFGStmt<BinaryOperator>(
566+
isPointerComparisonOperatorCall("!="),
567+
[](const BinaryOperator *Expr, const MatchFinder::MatchResult &,
568+
LatticeTransferState &State) {
569+
transferPointerComparisonOperator(Expr, State,
570+
/*IsNegative=*/true);
571+
})
485572
.CaseOfCFGStmt<CallExpr>(isOkStatusCall(), transferOkStatusCall)
486573
.CaseOfCFGStmt<CallExpr>(isNotOkStatusCall(), transferNotOkStatusCall)
574+
.CaseOfCFGStmt<CXXMemberCallExpr>(isStatusOrMemberCallWithName("emplace"),
575+
transferEmplaceCall)
487576
.Build();
488577
}
489578

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,12 @@ void AArch64TargetInfo::getTargetDefinesARMV96A(const LangOptions &Opts,
398398
getTargetDefinesARMV95A(Opts, Builder);
399399
}
400400

401+
void AArch64TargetInfo::getTargetDefinesARMV97A(const LangOptions &Opts,
402+
MacroBuilder &Builder) const {
403+
// Armv9.7-A does not have a v8.* equivalent, but is a superset of v9.6-A.
404+
getTargetDefinesARMV96A(Opts, Builder);
405+
}
406+
401407
void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
402408
MacroBuilder &Builder) const {
403409
// Target identification.
@@ -714,6 +720,8 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
714720
getTargetDefinesARMV95A(Opts, Builder);
715721
else if (*ArchInfo == llvm::AArch64::ARMV9_6A)
716722
getTargetDefinesARMV96A(Opts, Builder);
723+
else if (*ArchInfo == llvm::AArch64::ARMV9_7A)
724+
getTargetDefinesARMV97A(Opts, Builder);
717725

718726
// All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8|16) builtins work.
719727
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
@@ -1152,6 +1160,9 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
11521160
if (Feature == "+v9.6a" &&
11531161
ArchInfo->Version < llvm::AArch64::ARMV9_6A.Version)
11541162
ArchInfo = &llvm::AArch64::ARMV9_6A;
1163+
if (Feature == "+v9.7a" &&
1164+
ArchInfo->Version < llvm::AArch64::ARMV9_7A.Version)
1165+
ArchInfo = &llvm::AArch64::ARMV9_7A;
11551166
if (Feature == "+v8r")
11561167
ArchInfo = &llvm::AArch64::ARMV8R;
11571168
if (Feature == "+fullfp16") {

clang/lib/Basic/Targets/AArch64.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
190190
MacroBuilder &Builder) const;
191191
void getTargetDefinesARMV96A(const LangOptions &Opts,
192192
MacroBuilder &Builder) const;
193+
void getTargetDefinesARMV97A(const LangOptions &Opts,
194+
MacroBuilder &Builder) const;
193195
void getTargetDefines(const LangOptions &Opts,
194196
MacroBuilder &Builder) const override;
195197

0 commit comments

Comments
 (0)