Skip to content

Commit 3c1e721

Browse files
committed
[𝘀𝗽𝗿] changes introduced through rebase
Created using spr 1.3.8-beta.1 [skip ci]
1 parent ebdc34f commit 3c1e721

File tree

10 files changed

+89
-78
lines changed

10 files changed

+89
-78
lines changed

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/ByteCode/InterpBuiltin.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,38 +1311,39 @@ interp__builtin_ptrauth_string_discriminator(InterpState &S, CodePtr OpPC,
13111311
static bool interp__builtin_infer_alloc_token(InterpState &S, CodePtr OpPC,
13121312
const InterpFrame *Frame,
13131313
const CallExpr *Call) {
1314-
const ASTContext &Ctx = S.getASTContext();
1315-
const uint64_t BitWidth = Ctx.getTypeSize(Ctx.getSizeType());
1316-
const auto Mode =
1317-
Ctx.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
1318-
const uint64_t MaxTokens =
1319-
Ctx.getLangOpts().AllocTokenMax.value_or(~0ULL >> (64 - BitWidth));
1314+
const ASTContext &ASTCtx = S.getASTContext();
1315+
uint64_t BitWidth = ASTCtx.getTypeSize(ASTCtx.getSizeType());
1316+
auto Mode =
1317+
ASTCtx.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
1318+
uint64_t MaxTokens =
1319+
ASTCtx.getLangOpts().AllocTokenMax.value_or(~0ULL >> (64 - BitWidth));
13201320

13211321
// We do not read any of the arguments; discard them.
13221322
for (int I = Call->getNumArgs() - 1; I >= 0; --I)
13231323
discard(S.Stk, *S.getContext().classify(Call->getArg(I)));
13241324

13251325
// Note: Type inference from a surrounding cast is not supported in
13261326
// constexpr evaluation.
1327-
QualType AllocType = infer_alloc::inferPossibleType(Call, Ctx, nullptr);
1327+
QualType AllocType = infer_alloc::inferPossibleType(Call, ASTCtx, nullptr);
13281328
if (AllocType.isNull()) {
1329-
S.CCEDiag(Call) << "could not infer allocation type";
1329+
S.CCEDiag(Call,
1330+
diag::note_constexpr_infer_alloc_token_type_inference_failed);
13301331
return false;
13311332
}
13321333

1333-
auto ATMD = infer_alloc::getAllocTokenMetadata(AllocType, Ctx);
1334+
auto ATMD = infer_alloc::getAllocTokenMetadata(AllocType, ASTCtx);
13341335
if (!ATMD) {
1335-
S.CCEDiag(Call) << "could not get token metadata for type";
1336+
S.CCEDiag(Call, diag::note_constexpr_infer_alloc_token_no_metadata);
13361337
return false;
13371338
}
13381339

1339-
auto MaybeToken = llvm::getAllocTokenHash(Mode, *ATMD, MaxTokens);
1340+
auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
13401341
if (!MaybeToken) {
1341-
S.CCEDiag(Call) << "stateful alloc token mode not supported in constexpr";
1342+
S.CCEDiag(Call, diag::note_constexpr_infer_alloc_token_stateful_mode);
13421343
return false;
13431344
}
13441345

1345-
pushInteger(S, llvm::APInt(BitWidth, *MaybeToken), Ctx.getSizeType());
1346+
pushInteger(S, llvm::APInt(BitWidth, *MaybeToken), ASTCtx.getSizeType());
13461347
return true;
13471348
}
13481349

clang/lib/AST/ExprConstant.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14421,18 +14421,19 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1442114421
// can be checked with __builtin_constant_p(...).
1442214422
QualType AllocType = infer_alloc::inferPossibleType(E, Info.Ctx, nullptr);
1442314423
if (AllocType.isNull())
14424-
return Error(E);
14424+
return Error(
14425+
E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
1442514426
auto ATMD = infer_alloc::getAllocTokenMetadata(AllocType, Info.Ctx);
1442614427
if (!ATMD)
14427-
return Error(E);
14428+
return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
1442814429
auto Mode =
1442914430
Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
1443014431
uint64_t BitWidth = Info.Ctx.getTypeSize(Info.Ctx.getSizeType());
1443114432
uint64_t MaxTokens =
1443214433
Info.getLangOpts().AllocTokenMax.value_or(~0ULL >> (64 - BitWidth));
14433-
auto MaybeToken = llvm::getAllocTokenHash(Mode, *ATMD, MaxTokens);
14434+
auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
1443414435
if (!MaybeToken)
14435-
return Error(E);
14436+
return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
1443614437
return Success(llvm::APInt(BitWidth, *MaybeToken), E);
1443714438
}
1443814439

clang/lib/AST/InferAlloc.cpp

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@
1919
#include "clang/Basic/IdentifierTable.h"
2020
#include "llvm/ADT/SmallPtrSet.h"
2121

22-
namespace clang {
23-
namespace {
24-
bool typeContainsPointer(QualType T,
25-
llvm::SmallPtrSet<const RecordDecl *, 4> &VisitedRD,
26-
bool &IncompleteType) {
22+
using namespace clang;
23+
using namespace infer_alloc;
24+
25+
static bool
26+
typeContainsPointer(QualType T,
27+
llvm::SmallPtrSet<const RecordDecl *, 4> &VisitedRD,
28+
bool &IncompleteType) {
2729
QualType CanonicalType = T.getCanonicalType();
2830
if (CanonicalType->isPointerType())
2931
return true; // base case
@@ -70,7 +72,7 @@ bool typeContainsPointer(QualType T,
7072
}
7173

7274
/// Infer type from a simple sizeof expression.
73-
QualType inferTypeFromSizeofExpr(const Expr *E) {
75+
static QualType inferTypeFromSizeofExpr(const Expr *E) {
7476
const Expr *Arg = E->IgnoreParenImpCasts();
7577
if (const auto *UET = dyn_cast<UnaryExprOrTypeTraitExpr>(Arg)) {
7678
if (UET->getKind() == UETT_SizeOf) {
@@ -96,7 +98,7 @@ QualType inferTypeFromSizeofExpr(const Expr *E) {
9698
///
9799
/// malloc(sizeof(HasFlexArray) + sizeof(int) * 32); // infers 'HasFlexArray'
98100
///
99-
QualType inferPossibleTypeFromArithSizeofExpr(const Expr *E) {
101+
static QualType inferPossibleTypeFromArithSizeofExpr(const Expr *E) {
100102
const Expr *Arg = E->IgnoreParenImpCasts();
101103
// The argument is a lone sizeof expression.
102104
if (QualType T = inferTypeFromSizeofExpr(Arg); !T.isNull())
@@ -132,7 +134,7 @@ QualType inferPossibleTypeFromArithSizeofExpr(const Expr *E) {
132134
/// size_t my_size = sizeof(MyType);
133135
/// void *x = malloc(my_size); // infers 'MyType'
134136
///
135-
QualType inferPossibleTypeFromVarInitSizeofExpr(const Expr *E) {
137+
static QualType inferPossibleTypeFromVarInitSizeofExpr(const Expr *E) {
136138
const Expr *Arg = E->IgnoreParenImpCasts();
137139
if (const auto *DRE = dyn_cast<DeclRefExpr>(Arg)) {
138140
if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
@@ -148,21 +150,19 @@ QualType inferPossibleTypeFromVarInitSizeofExpr(const Expr *E) {
148150
///
149151
/// MyType *x = (MyType *)malloc(4096); // infers 'MyType'
150152
///
151-
QualType inferPossibleTypeFromCastExpr(const CallExpr *CallE,
152-
const CastExpr *CastE) {
153+
static QualType inferPossibleTypeFromCastExpr(const CallExpr *CallE,
154+
const CastExpr *CastE) {
153155
if (!CastE)
154156
return QualType();
155157
QualType PtrType = CastE->getType();
156158
if (PtrType->isPointerType())
157159
return PtrType->getPointeeType();
158160
return QualType();
159161
}
160-
} // anonymous namespace
161-
162-
namespace infer_alloc {
163162

164-
QualType inferPossibleType(const CallExpr *E, const ASTContext &Ctx,
165-
const CastExpr *CastE) {
163+
QualType clang::infer_alloc::inferPossibleType(const CallExpr *E,
164+
const ASTContext &Ctx,
165+
const CastExpr *CastE) {
166166
QualType AllocType;
167167
// First check arguments.
168168
for (const Expr *Arg : E->arguments()) {
@@ -179,7 +179,7 @@ QualType inferPossibleType(const CallExpr *E, const ASTContext &Ctx,
179179
}
180180

181181
std::optional<llvm::AllocTokenMetadata>
182-
getAllocTokenMetadata(QualType T, const ASTContext &Ctx) {
182+
clang::infer_alloc::getAllocTokenMetadata(QualType T, const ASTContext &Ctx) {
183183
llvm::AllocTokenMetadata ATMD;
184184

185185
// Get unique type name.
@@ -199,6 +199,3 @@ getAllocTokenMetadata(QualType T, const ASTContext &Ctx) {
199199

200200
return ATMD;
201201
}
202-
203-
} // namespace infer_alloc
204-
} // namespace clang

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4565,14 +4565,7 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
45654565

45664566
if (const auto *Arg = Args.getLastArg(options::OPT_falloc_token_mode_EQ)) {
45674567
StringRef S = Arg->getValue();
4568-
auto Mode = llvm::StringSwitch<std::optional<llvm::AllocTokenMode>>(S)
4569-
.Case("increment", llvm::AllocTokenMode::Increment)
4570-
.Case("random", llvm::AllocTokenMode::Random)
4571-
.Case("typehash", llvm::AllocTokenMode::TypeHash)
4572-
.Case("typehashpointersplit",
4573-
llvm::AllocTokenMode::TypeHashPointerSplit)
4574-
.Default(std::nullopt);
4575-
if (Mode)
4568+
if (auto Mode = getAllocTokenModeFromString(S))
45764569
Opts.AllocTokenMode = Mode;
45774570
else
45784571
Diags.Report(diag::err_drv_invalid_value) << Arg->getAsString(Args) << S;

clang/test/SemaCXX/alloc-token.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@
77
#error "missing __builtin_infer_alloc_token"
88
#endif
99

10-
#ifndef TOKEN_MAX
11-
#define TOKEN_MAX 0
12-
#endif
13-
1410
struct NoPtr {
1511
int x;
1612
long y;
@@ -27,11 +23,15 @@ static_assert(__builtin_infer_alloc_token(sizeof(int)) == 2689373973731826898ULL
2723
static_assert(__builtin_infer_alloc_token(sizeof(char*)) == 2250492667400517147ULL);
2824
static_assert(__builtin_infer_alloc_token(sizeof(NoPtr)) == 7465259095297095368ULL);
2925
static_assert(__builtin_infer_alloc_token(sizeof(WithPtr)) == 11898882936532569145ULL);
30-
#elif TOKEN_MAX == 2
26+
#elif defined(TOKEN_MAX)
27+
# if TOKEN_MAX == 2
3128
static_assert(__builtin_infer_alloc_token(sizeof(int)) == 0);
3229
static_assert(__builtin_infer_alloc_token(sizeof(char*)) == 1);
3330
static_assert(__builtin_infer_alloc_token(sizeof(NoPtr)) == 0);
3431
static_assert(__builtin_infer_alloc_token(sizeof(WithPtr)) == 1);
32+
# else
33+
# error "unhandled TOKEN_MAX case"
34+
# endif
3535
#else
3636
static_assert(__builtin_infer_alloc_token(sizeof(int)) == 2689373973731826898ULL);
3737
static_assert(__builtin_infer_alloc_token(sizeof(char*)) == 11473864704255292954ULL);
@@ -53,5 +53,6 @@ static_assert(__builtin_infer_alloc_token(sizeof(NoPtr) << 8) == get_token<NoPtr
5353
void negative_tests() {
5454
__builtin_infer_alloc_token(); // expected-error {{too few arguments to function call}}
5555
__builtin_infer_alloc_token((void)0); // expected-error {{argument may not have 'void' type}}
56-
constexpr auto inference_fail = __builtin_infer_alloc_token(123); // expected-error {{must be initialized by a constant expression}}
56+
constexpr auto inference_fail = __builtin_infer_alloc_token(123); // expected-error {{must be initialized by a constant expression}} \
57+
// expected-note {{could not infer allocation type for __builtin_infer_alloc_token}}
5758
}

llvm/include/llvm/Support/AllocToken.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define LLVM_SUPPORT_ALLOCTOKEN_H
1515

1616
#include "llvm/ADT/SmallString.h"
17+
#include "llvm/ADT/StringRef.h"
1718
#include <cstdint>
1819
#include <optional>
1920

@@ -40,6 +41,11 @@ enum class AllocTokenMode {
4041
inline constexpr AllocTokenMode DefaultAllocTokenMode =
4142
AllocTokenMode::TypeHashPointerSplit;
4243

44+
/// Returns the AllocTokenMode from its canonical string name; if an invalid
45+
/// name was provided returns nullopt.
46+
LLVM_ABI std::optional<AllocTokenMode>
47+
getAllocTokenModeFromString(StringRef Name);
48+
4349
/// Metadata about an allocation used to generate a token ID.
4450
struct AllocTokenMetadata {
4551
SmallString<64> TypeName;
@@ -53,9 +59,9 @@ struct AllocTokenMetadata {
5359
/// \param Metadata The metadata about the allocation.
5460
/// \param MaxTokens The maximum number of tokens (must not be 0)
5561
/// \return The calculated allocation token ID, or std::nullopt.
56-
std::optional<uint64_t> getAllocTokenHash(AllocTokenMode Mode,
57-
const AllocTokenMetadata &Metadata,
58-
uint64_t MaxTokens);
62+
LLVM_ABI std::optional<uint64_t>
63+
getAllocToken(AllocTokenMode Mode, const AllocTokenMetadata &Metadata,
64+
uint64_t MaxTokens);
5965

6066
} // end namespace llvm
6167

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,14 +1102,7 @@ Expected<AllocTokenOptions> parseAllocTokenPassOptions(StringRef Params) {
11021102
std::tie(ParamName, Params) = Params.split(';');
11031103

11041104
if (ParamName.consume_front("mode=")) {
1105-
auto Mode = StringSwitch<std::optional<AllocTokenMode>>(ParamName)
1106-
.Case("increment", AllocTokenMode::Increment)
1107-
.Case("random", AllocTokenMode::Random)
1108-
.Case("typehash", AllocTokenMode::TypeHash)
1109-
.Case("typehashpointersplit",
1110-
AllocTokenMode::TypeHashPointerSplit)
1111-
.Default(std::nullopt);
1112-
if (Mode)
1105+
if (auto Mode = getAllocTokenModeFromString(ParamName))
11131106
Result.Mode = *Mode;
11141107
else
11151108
return make_error<StringError>(

llvm/lib/Support/AllocToken.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,46 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "llvm/Support/AllocToken.h"
14+
#include "llvm/ADT/StringSwitch.h"
1415
#include "llvm/Support/ErrorHandling.h"
1516
#include "llvm/Support/SipHash.h"
1617

17-
namespace llvm {
18-
std::optional<uint64_t> getAllocTokenHash(AllocTokenMode Mode,
19-
const AllocTokenMetadata &Metadata,
20-
uint64_t MaxTokens) {
21-
assert(MaxTokens && "Must provide concrete max tokens");
18+
using namespace llvm;
19+
20+
std::optional<AllocTokenMode>
21+
llvm::getAllocTokenModeFromString(StringRef Name) {
22+
return StringSwitch<std::optional<AllocTokenMode>>(Name)
23+
.Case("increment", AllocTokenMode::Increment)
24+
.Case("random", AllocTokenMode::Random)
25+
.Case("typehash", AllocTokenMode::TypeHash)
26+
.Case("typehashpointersplit", AllocTokenMode::TypeHashPointerSplit)
27+
.Default(std::nullopt);
28+
}
29+
30+
static uint64_t getStableHash(const AllocTokenMetadata &Metadata,
31+
uint64_t MaxTokens) {
32+
return getStableSipHash(Metadata.TypeName) % MaxTokens;
33+
}
34+
35+
std::optional<uint64_t> llvm::getAllocToken(AllocTokenMode Mode,
36+
const AllocTokenMetadata &Metadata,
37+
uint64_t MaxTokens) {
38+
assert(MaxTokens && "Must provide non-zero max tokens");
2239

2340
switch (Mode) {
2441
case AllocTokenMode::Increment:
2542
case AllocTokenMode::Random:
2643
// Stateful modes cannot be implemented as a pure function.
2744
return std::nullopt;
2845

29-
case AllocTokenMode::TypeHash: {
30-
return getStableSipHash(Metadata.TypeName) % MaxTokens;
31-
}
46+
case AllocTokenMode::TypeHash:
47+
return getStableHash(Metadata, MaxTokens);
3248

3349
case AllocTokenMode::TypeHashPointerSplit: {
3450
if (MaxTokens == 1)
3551
return 0;
3652
const uint64_t HalfTokens = MaxTokens / 2;
37-
uint64_t Hash = getStableSipHash(Metadata.TypeName) % HalfTokens;
53+
uint64_t Hash = getStableHash(Metadata, HalfTokens);
3854
if (Metadata.ContainsPointer)
3955
Hash += HalfTokens;
4056
return Hash;
@@ -43,4 +59,3 @@ std::optional<uint64_t> getAllocTokenHash(AllocTokenMode Mode,
4359

4460
llvm_unreachable("");
4561
}
46-
} // namespace llvm

llvm/lib/Transforms/Instrumentation/AllocToken.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,7 @@ class TypeHashMode : public ModeBase {
189189
if (MDNode *N = getAllocTokenMetadata(CB)) {
190190
MDString *S = cast<MDString>(N->getOperand(0));
191191
AllocTokenMetadata Metadata{S->getString(), containsPointer(N)};
192-
if (auto Token =
193-
getAllocTokenHash(TokenMode::TypeHash, Metadata, MaxTokens))
192+
if (auto Token = getAllocToken(TokenMode::TypeHash, Metadata, MaxTokens))
194193
return *Token;
195194
}
196195
// Fallback.
@@ -222,8 +221,8 @@ class TypeHashPointerSplitMode : public TypeHashMode {
222221
if (MDNode *N = getAllocTokenMetadata(CB)) {
223222
MDString *S = cast<MDString>(N->getOperand(0));
224223
AllocTokenMetadata Metadata{S->getString(), containsPointer(N)};
225-
if (auto Token = getAllocTokenHash(TokenMode::TypeHashPointerSplit,
226-
Metadata, MaxTokens))
224+
if (auto Token = getAllocToken(TokenMode::TypeHashPointerSplit, Metadata,
225+
MaxTokens))
227226
return *Token;
228227
}
229228
// Pick the fallback token (ClFallbackToken), which by default is 0, meaning
@@ -357,9 +356,8 @@ bool AllocToken::instrumentFunction(Function &F) {
357356
}
358357

359358
if (!IntrinsicInsts.empty()) {
360-
for (auto *II : IntrinsicInsts) {
359+
for (auto *II : IntrinsicInsts)
361360
replaceIntrinsicInst(II, ORE);
362-
}
363361
Modified = true;
364362
NumFunctionsModified++;
365363
}
@@ -381,7 +379,7 @@ AllocToken::shouldInstrumentCall(const CallBase &CB,
381379
if (TLI.getLibFunc(*Callee, Func)) {
382380
if (isInstrumentableLibFunc(Func, CB, TLI))
383381
return Func;
384-
} else if (Options.Extended && getAllocTokenMetadata(CB)) {
382+
} else if (Options.Extended && CB.getMetadata(LLVMContext::MD_alloc_token)) {
385383
return NotLibFunc;
386384
}
387385

0 commit comments

Comments
 (0)