Skip to content

Commit bc294b3

Browse files
committed
merge main into amd-staging
2 parents 6eeca37 + 5754418 commit bc294b3

File tree

173 files changed

+4391
-1496
lines changed

Some content is hidden

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

173 files changed

+4391
-1496
lines changed

clang-tools-extra/clang-include-fixer/IncludeFixer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ bool IncludeFixerActionFactory::runInvocation(
9090

9191
// Set up Clang.
9292
CompilerInstance Compiler(std::move(Invocation), std::move(PCHContainerOps));
93+
Compiler.setVirtualFileSystem(Files->getVirtualFileSystemPtr());
9394
Compiler.setFileManager(Files);
9495

9596
// Create the compiler's actual diagnostics engine. We want to drop all

clang/include/clang/Frontend/ASTUnit.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,11 @@ class ASTUnit {
499499
return *PPOpts;
500500
}
501501

502+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> getVirtualFileSystemPtr() {
503+
// FIXME: Don't defer VFS ownership to the FileManager.
504+
return FileMgr->getVirtualFileSystemPtr();
505+
}
506+
502507
const FileManager &getFileManager() const { return *FileMgr; }
503508
FileManager &getFileManager() { return *FileMgr; }
504509
IntrusiveRefCntPtr<FileManager> getFileManagerPtr() { return FileMgr; }

clang/include/clang/Frontend/CompilerInstance.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ class CompilerInstance : public ModuleLoader {
460460
FileMgr.resetWithoutRelease();
461461
}
462462

463-
/// Replace the current file manager and virtual file system.
463+
/// Replace the current file manager.
464464
void setFileManager(IntrusiveRefCntPtr<FileManager> Value);
465465

466466
/// @}

clang/include/clang/Sema/Sema.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,15 +1321,11 @@ class Sema final : public SemaBase {
13211321

13221322
/// Callback to the parser to parse templated functions when needed.
13231323
typedef void LateTemplateParserCB(void *P, LateParsedTemplate &LPT);
1324-
typedef void LateTemplateParserCleanupCB(void *P);
13251324
LateTemplateParserCB *LateTemplateParser;
1326-
LateTemplateParserCleanupCB *LateTemplateParserCleanup;
13271325
void *OpaqueParser;
13281326

1329-
void SetLateTemplateParser(LateTemplateParserCB *LTP,
1330-
LateTemplateParserCleanupCB *LTPCleanup, void *P) {
1327+
void SetLateTemplateParser(LateTemplateParserCB *LTP, void *P) {
13311328
LateTemplateParser = LTP;
1332-
LateTemplateParserCleanup = LTPCleanup;
13331329
OpaqueParser = P;
13341330
}
13351331

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

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,37 @@ static auto valueOperatorCall() {
137137
isStatusOrOperatorCallWithName("->")));
138138
}
139139

140+
static clang::ast_matchers::TypeMatcher statusType() {
141+
using namespace ::clang::ast_matchers; // NOLINT: Too many names
142+
return hasCanonicalType(qualType(hasDeclaration(statusClass())));
143+
}
144+
145+
static auto isComparisonOperatorCall(llvm::StringRef operator_name) {
146+
using namespace ::clang::ast_matchers; // NOLINT: Too many names
147+
return cxxOperatorCallExpr(
148+
hasOverloadedOperatorName(operator_name), argumentCountIs(2),
149+
hasArgument(0, anyOf(hasType(statusType()), hasType(statusOrType()))),
150+
hasArgument(1, anyOf(hasType(statusType()), hasType(statusOrType()))));
151+
}
152+
153+
static auto isOkStatusCall() {
154+
using namespace ::clang::ast_matchers; // NOLINT: Too many names
155+
return callExpr(callee(functionDecl(hasName("::absl::OkStatus"))));
156+
}
157+
158+
static auto isNotOkStatusCall() {
159+
using namespace ::clang::ast_matchers; // NOLINT: Too many names
160+
return callExpr(callee(functionDecl(hasAnyName(
161+
"::absl::AbortedError", "::absl::AlreadyExistsError",
162+
"::absl::CancelledError", "::absl::DataLossError",
163+
"::absl::DeadlineExceededError", "::absl::FailedPreconditionError",
164+
"::absl::InternalError", "::absl::InvalidArgumentError",
165+
"::absl::NotFoundError", "::absl::OutOfRangeError",
166+
"::absl::PermissionDeniedError", "::absl::ResourceExhaustedError",
167+
"::absl::UnauthenticatedError", "::absl::UnavailableError",
168+
"::absl::UnimplementedError", "::absl::UnknownError"))));
169+
}
170+
140171
static auto
141172
buildDiagnoseMatchSwitch(const UncheckedStatusOrAccessModelOptions &Options) {
142173
return CFGMatchSwitchBuilder<const Environment,
@@ -312,6 +343,118 @@ static void transferStatusUpdateCall(const CXXMemberCallExpr *Expr,
312343
State.Env.setValue(locForOk(*ThisLoc), NewVal);
313344
}
314345

346+
static BoolValue *evaluateStatusEquality(RecordStorageLocation &LhsStatusLoc,
347+
RecordStorageLocation &RhsStatusLoc,
348+
Environment &Env) {
349+
auto &A = Env.arena();
350+
// Logically, a Status object is composed of an error code that could take one
351+
// of multiple possible values, including the "ok" value. We track whether a
352+
// Status object has an "ok" value and represent this as an `ok` bit. Equality
353+
// of Status objects compares their error codes. Therefore, merely comparing
354+
// the `ok` bits isn't sufficient: when two Status objects are assigned non-ok
355+
// error codes the equality of their respective error codes matters. Since we
356+
// only track the `ok` bits, we can't make any conclusions about equality when
357+
// we know that two Status objects have non-ok values.
358+
359+
auto &LhsOkVal = valForOk(LhsStatusLoc, Env);
360+
auto &RhsOkVal = valForOk(RhsStatusLoc, Env);
361+
362+
auto &Res = Env.makeAtomicBoolValue();
363+
364+
// lhs && rhs => res (a.k.a. !res => !lhs || !rhs)
365+
Env.assume(A.makeImplies(A.makeAnd(LhsOkVal.formula(), RhsOkVal.formula()),
366+
Res.formula()));
367+
// res => (lhs == rhs)
368+
Env.assume(A.makeImplies(
369+
Res.formula(), A.makeEquals(LhsOkVal.formula(), RhsOkVal.formula())));
370+
371+
return &Res;
372+
}
373+
374+
static BoolValue *
375+
evaluateStatusOrEquality(RecordStorageLocation &LhsStatusOrLoc,
376+
RecordStorageLocation &RhsStatusOrLoc,
377+
Environment &Env) {
378+
auto &A = Env.arena();
379+
// Logically, a StatusOr<T> object is composed of two values - a Status and a
380+
// value of type T. Equality of StatusOr objects compares both values.
381+
// Therefore, merely comparing the `ok` bits of the Status values isn't
382+
// sufficient. When two StatusOr objects are engaged, the equality of their
383+
// respective values of type T matters. Similarly, when two StatusOr objects
384+
// have Status values that have non-ok error codes, the equality of the error
385+
// codes matters. Since we only track the `ok` bits of the Status values, we
386+
// can't make any conclusions about equality when we know that two StatusOr
387+
// objects are engaged or when their Status values contain non-ok error codes.
388+
auto &LhsOkVal = valForOk(locForStatus(LhsStatusOrLoc), Env);
389+
auto &RhsOkVal = valForOk(locForStatus(RhsStatusOrLoc), Env);
390+
auto &res = Env.makeAtomicBoolValue();
391+
392+
// res => (lhs == rhs)
393+
Env.assume(A.makeImplies(
394+
res.formula(), A.makeEquals(LhsOkVal.formula(), RhsOkVal.formula())));
395+
return &res;
396+
}
397+
398+
static BoolValue *evaluateEquality(const Expr *LhsExpr, const Expr *RhsExpr,
399+
Environment &Env) {
400+
// Check the type of both sides in case an operator== is added that admits
401+
// different types.
402+
if (isStatusOrType(LhsExpr->getType()) &&
403+
isStatusOrType(RhsExpr->getType())) {
404+
auto *LhsStatusOrLoc = Env.get<RecordStorageLocation>(*LhsExpr);
405+
if (LhsStatusOrLoc == nullptr)
406+
return nullptr;
407+
auto *RhsStatusOrLoc = Env.get<RecordStorageLocation>(*RhsExpr);
408+
if (RhsStatusOrLoc == nullptr)
409+
return nullptr;
410+
411+
return evaluateStatusOrEquality(*LhsStatusOrLoc, *RhsStatusOrLoc, Env);
412+
}
413+
if (isStatusType(LhsExpr->getType()) && isStatusType(RhsExpr->getType())) {
414+
auto *LhsStatusLoc = Env.get<RecordStorageLocation>(*LhsExpr);
415+
if (LhsStatusLoc == nullptr)
416+
return nullptr;
417+
418+
auto *RhsStatusLoc = Env.get<RecordStorageLocation>(*RhsExpr);
419+
if (RhsStatusLoc == nullptr)
420+
return nullptr;
421+
422+
return evaluateStatusEquality(*LhsStatusLoc, *RhsStatusLoc, Env);
423+
}
424+
return nullptr;
425+
}
426+
427+
static void transferComparisonOperator(const CXXOperatorCallExpr *Expr,
428+
LatticeTransferState &State,
429+
bool IsNegative) {
430+
auto *LhsAndRhsVal =
431+
evaluateEquality(Expr->getArg(0), Expr->getArg(1), State.Env);
432+
if (LhsAndRhsVal == nullptr)
433+
return;
434+
435+
if (IsNegative)
436+
State.Env.setValue(*Expr, State.Env.makeNot(*LhsAndRhsVal));
437+
else
438+
State.Env.setValue(*Expr, *LhsAndRhsVal);
439+
}
440+
441+
static void transferOkStatusCall(const CallExpr *Expr,
442+
const MatchFinder::MatchResult &,
443+
LatticeTransferState &State) {
444+
auto &OkVal =
445+
initializeStatus(State.Env.getResultObjectLocation(*Expr), State.Env);
446+
State.Env.assume(OkVal.formula());
447+
}
448+
449+
static void transferNotOkStatusCall(const CallExpr *Expr,
450+
const MatchFinder::MatchResult &,
451+
LatticeTransferState &State) {
452+
auto &OkVal =
453+
initializeStatus(State.Env.getResultObjectLocation(*Expr), State.Env);
454+
auto &A = State.Env.arena();
455+
State.Env.assume(A.makeNot(OkVal.formula()));
456+
}
457+
315458
CFGMatchSwitch<LatticeTransferState>
316459
buildTransferMatchSwitch(ASTContext &Ctx,
317460
CFGMatchSwitchBuilder<LatticeTransferState> Builder) {
@@ -325,6 +468,22 @@ buildTransferMatchSwitch(ASTContext &Ctx,
325468
transferStatusOkCall)
326469
.CaseOfCFGStmt<CXXMemberCallExpr>(isStatusMemberCallWithName("Update"),
327470
transferStatusUpdateCall)
471+
.CaseOfCFGStmt<CXXOperatorCallExpr>(
472+
isComparisonOperatorCall("=="),
473+
[](const CXXOperatorCallExpr *Expr, const MatchFinder::MatchResult &,
474+
LatticeTransferState &State) {
475+
transferComparisonOperator(Expr, State,
476+
/*IsNegative=*/false);
477+
})
478+
.CaseOfCFGStmt<CXXOperatorCallExpr>(
479+
isComparisonOperatorCall("!="),
480+
[](const CXXOperatorCallExpr *Expr, const MatchFinder::MatchResult &,
481+
LatticeTransferState &State) {
482+
transferComparisonOperator(Expr, State,
483+
/*IsNegative=*/true);
484+
})
485+
.CaseOfCFGStmt<CallExpr>(isOkStatusCall(), transferOkStatusCall)
486+
.CaseOfCFGStmt<CallExpr>(isNotOkStatusCall(), transferNotOkStatusCall)
328487
.Build();
329488
}
330489

clang/lib/CIR/CodeGen/CIRGenAsm.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ mlir::LogicalResult CIRGenFunction::emitAsmStmt(const AsmStmt &s) {
117117

118118
bool hasSideEffect = s.isVolatile() || s.getNumOutputs() == 0;
119119

120-
cir::InlineAsmOp ia = builder.create<cir::InlineAsmOp>(
121-
getLoc(s.getAsmLoc()), resultType, operands, asmString, constraints,
122-
hasSideEffect, inferFlavor(cgm, s), mlir::ArrayAttr());
120+
cir::InlineAsmOp ia = cir::InlineAsmOp::create(
121+
builder, getLoc(s.getAsmLoc()), resultType, operands, asmString,
122+
constraints, hasSideEffect, inferFlavor(cgm, s), mlir::ArrayAttr());
123123

124124
if (isGCCAsmGoto) {
125125
assert(!cir::MissingFeatures::asmGoto());

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ static RValue emitBuiltinBitOp(CIRGenFunction &cgf, const CallExpr *e,
4646
Op op;
4747
if constexpr (std::is_same_v<Op, cir::BitClzOp> ||
4848
std::is_same_v<Op, cir::BitCtzOp>)
49-
op = builder.create<Op>(cgf.getLoc(e->getSourceRange()), arg, poisonZero);
49+
op = Op::create(builder, cgf.getLoc(e->getSourceRange()), arg, poisonZero);
5050
else
51-
op = builder.create<Op>(cgf.getLoc(e->getSourceRange()), arg);
51+
op = Op::create(builder, cgf.getLoc(e->getSourceRange()), arg);
5252

5353
mlir::Value result = op.getResult();
5454
mlir::Type exprTy = cgf.convertType(e->getType());
@@ -67,8 +67,8 @@ RValue CIRGenFunction::emitRotate(const CallExpr *e, bool isRotateLeft) {
6767
// to the type of input when necessary.
6868
assert(!cir::MissingFeatures::msvcBuiltins());
6969

70-
auto r = builder.create<cir::RotateOp>(getLoc(e->getSourceRange()), input,
71-
amount, isRotateLeft);
70+
auto r = cir::RotateOp::create(builder, getLoc(e->getSourceRange()), input,
71+
amount, isRotateLeft);
7272
return RValue::get(r);
7373
}
7474

@@ -227,14 +227,14 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
227227
return RValue::get(nullptr);
228228

229229
mlir::Value argValue = emitCheckedArgForAssume(e->getArg(0));
230-
builder.create<cir::AssumeOp>(loc, argValue);
230+
cir::AssumeOp::create(builder, loc, argValue);
231231
return RValue::get(nullptr);
232232
}
233233

234234
case Builtin::BI__builtin_assume_separate_storage: {
235235
mlir::Value value0 = emitScalarExpr(e->getArg(0));
236236
mlir::Value value1 = emitScalarExpr(e->getArg(1));
237-
builder.create<cir::AssumeSepStorageOp>(loc, value0, value1);
237+
cir::AssumeSepStorageOp::create(builder, loc, value0, value1);
238238
return RValue::get(nullptr);
239239
}
240240

@@ -363,8 +363,8 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
363363
probability);
364364
}
365365

366-
auto result = builder.create<cir::ExpectOp>(
367-
loc, argValue.getType(), argValue, expectedValue, probAttr);
366+
auto result = cir::ExpectOp::create(builder, loc, argValue.getType(),
367+
argValue, expectedValue, probAttr);
368368
return RValue::get(result);
369369
}
370370

@@ -375,15 +375,15 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
375375
case Builtin::BI_byteswap_ulong:
376376
case Builtin::BI_byteswap_uint64: {
377377
mlir::Value arg = emitScalarExpr(e->getArg(0));
378-
return RValue::get(builder.create<cir::ByteSwapOp>(loc, arg));
378+
return RValue::get(cir::ByteSwapOp::create(builder, loc, arg));
379379
}
380380

381381
case Builtin::BI__builtin_bitreverse8:
382382
case Builtin::BI__builtin_bitreverse16:
383383
case Builtin::BI__builtin_bitreverse32:
384384
case Builtin::BI__builtin_bitreverse64: {
385385
mlir::Value arg = emitScalarExpr(e->getArg(0));
386-
return RValue::get(builder.create<cir::BitReverseOp>(loc, arg));
386+
return RValue::get(cir::BitReverseOp::create(builder, loc, arg));
387387
}
388388

389389
case Builtin::BI__builtin_rotateleft8:

clang/lib/CIR/CodeGen/CIRGenCXX.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ static void emitDeclDestroy(CIRGenFunction &cgf, const VarDecl *vd,
151151
// Don't confuse lexical cleanup.
152152
builder.clearInsertionPoint();
153153
} else {
154-
builder.create<cir::YieldOp>(addr.getLoc());
154+
cir::YieldOp::create(builder, addr.getLoc());
155155
}
156156
}
157157

clang/lib/CIR/CodeGen/CIRGenClass.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -725,8 +725,9 @@ void CIRGenFunction::emitCXXAggrConstructorCall(
725725
// Emit the constructor call that will execute for every array element.
726726
mlir::Value arrayOp =
727727
builder.createPtrBitcast(arrayBase.getPointer(), arrayTy);
728-
builder.create<cir::ArrayCtor>(
729-
*currSrcLoc, arrayOp, [&](mlir::OpBuilder &b, mlir::Location loc) {
728+
cir::ArrayCtor::create(
729+
builder, *currSrcLoc, arrayOp,
730+
[&](mlir::OpBuilder &b, mlir::Location loc) {
730731
mlir::BlockArgument arg =
731732
b.getInsertionBlock()->addArgument(ptrToElmType, loc);
732733
Address curAddr = Address(arg, elementType, eltAlignment);
@@ -738,7 +739,7 @@ void CIRGenFunction::emitCXXAggrConstructorCall(
738739
emitCXXConstructorCall(ctor, Ctor_Complete,
739740
/*ForVirtualBase=*/false,
740741
/*Delegating=*/false, currAVS, e);
741-
builder.create<cir::YieldOp>(loc);
742+
cir::YieldOp::create(builder, loc);
742743
});
743744
}
744745
}

0 commit comments

Comments
 (0)