Skip to content

Commit e905031

Browse files
committed
Merge branch 'main' of https://github.com/llvm/llvm-project into rocdl_is_bad_for_spirv
2 parents 36e550c + 88ae5bd commit e905031

File tree

106 files changed

+2399
-2188
lines changed

Some content is hidden

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

106 files changed

+2399
-2188
lines changed

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ Changes in existing checks
112112
<clang-tidy/checks/bugprone/unchecked-optional-access>` fixing false
113113
positives from smart pointer accessors repeated in checking ``has_value``
114114
and accessing ``value``. The option `IgnoreSmartPointerDereference` should
115-
no longer be needed and will be removed.
115+
no longer be needed and will be removed. Also fixing false positive from
116+
const reference accessors to objects containing optional member.
116117

117118
- Improved :doc:`bugprone-unsafe-functions
118119
<clang-tidy/checks/bugprone/unsafe-functions>` check to allow specifying

clang-tools-extra/docs/clang-tidy/Contributing.rst

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ After choosing the module and the name for the check, run the
149149
``clang-tidy/add_new_check.py`` script to create the skeleton of the check and
150150
plug it to :program:`clang-tidy`. It's the recommended way of adding new checks.
151151

152+
By default, the new check will apply only to C++ code. If it should apply under
153+
different language options, use the ``--language`` script's parameter.
154+
152155
If we want to create a `readability-awesome-function-names`, we would run:
153156

154157
.. code-block:: console
@@ -171,9 +174,7 @@ Let's see in more detail at the check class definition:
171174

172175
#include "../ClangTidyCheck.h"
173176

174-
namespace clang {
175-
namespace tidy {
176-
namespace readability {
177+
namespace clang::tidy::readability {
177178

178179
...
179180
class AwesomeFunctionNamesCheck : public ClangTidyCheck {
@@ -182,11 +183,12 @@ Let's see in more detail at the check class definition:
182183
: ClangTidyCheck(Name, Context) {}
183184
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
184185
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
186+
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
187+
return LangOpts.CPlusPlus;
188+
}
185189
};
186190
187-
} // namespace readability
188-
} // namespace tidy
189-
} // namespace clang
191+
} // namespace clang::tidy::readability
190192

191193
...
192194

@@ -231,9 +233,6 @@ override the method ``registerPPCallbacks``. The ``add_new_check.py`` script
231233
does not generate an override for this method in the starting point for your
232234
new check.
233235

234-
If your check applies only under a specific set of language options, be sure
235-
to override the method ``isLanguageVersionSupported`` to reflect that.
236-
237236
Check development tips
238237
----------------------
239238

clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
6969
return create<cir::LoadOp>(loc, ptr);
7070
}
7171

72+
cir::StoreOp createStore(mlir::Location loc, mlir::Value val,
73+
mlir::Value dst) {
74+
return create<cir::StoreOp>(loc, val, dst);
75+
}
76+
7277
//
7378
// Block handling helpers
7479
// ----------------------

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,45 @@ def LoadOp : CIR_Op<"load", [
228228
// FIXME: add verifier.
229229
}
230230

231+
//===----------------------------------------------------------------------===//
232+
// StoreOp
233+
//===----------------------------------------------------------------------===//
234+
235+
def StoreOp : CIR_Op<"store", [
236+
TypesMatchWith<"type of 'value' matches pointee type of 'addr'",
237+
"addr", "value",
238+
"cast<PointerType>($_self).getPointee()">,
239+
DeclareOpInterfaceMethods<PromotableMemOpInterface>]> {
240+
241+
let summary = "Store value to memory address";
242+
let description = [{
243+
`cir.store` stores a value (first operand) to the memory address specified
244+
in the second operand. A unit attribute `volatile` can be used to indicate
245+
a volatile store. Store's can be marked atomic by using
246+
`atomic(<mem_order>)`.
247+
248+
`align` can be used to specify an alignment that's different from the
249+
default, which is computed from `result`'s type ABI data layout.
250+
251+
Example:
252+
253+
```mlir
254+
// Store a function argument to local storage, address in %0.
255+
cir.store %arg0, %0 : i32, !cir.ptr<i32>
256+
```
257+
}];
258+
259+
let arguments = (ins CIR_AnyType:$value,
260+
Arg<CIR_PointerType, "the address to store the value",
261+
[MemWrite]>:$addr);
262+
263+
let assemblyFormat = [{
264+
$value `,` $addr attr-dict `:` type($value) `,` qualified(type($addr))
265+
}];
266+
267+
// FIXME: add verifier.
268+
}
269+
231270
//===----------------------------------------------------------------------===//
232271
// ReturnOp
233272
//===----------------------------------------------------------------------===//

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ struct MissingFeatures {
5959
// Misc
6060
static bool scalarConversionOpts() { return false; }
6161
static bool tryEmitAsConstant() { return false; }
62+
static bool constructABIArgDirectExtend() { return false; }
6263
};
6364

6465
} // namespace cir

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,22 @@ void handleConstMemberCall(const CallExpr *CE,
580580
return;
581581
}
582582

583+
// Cache if the const method returns a reference
584+
if (RecordLoc != nullptr && CE->isGLValue()) {
585+
const FunctionDecl *DirectCallee = CE->getDirectCallee();
586+
if (DirectCallee == nullptr)
587+
return;
588+
589+
StorageLocation &Loc =
590+
State.Lattice.getOrCreateConstMethodReturnStorageLocation(
591+
*RecordLoc, DirectCallee, State.Env, [&](StorageLocation &Loc) {
592+
// no-op
593+
});
594+
595+
State.Env.setStorageLocation(*CE, Loc);
596+
return;
597+
}
598+
583599
// Cache if the const method returns a boolean or pointer type.
584600
// We may decide to cache other return types in the future.
585601
if (RecordLoc != nullptr &&

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2364,12 +2364,13 @@ template <typename NodeTy>
23642364
static std::optional<SourceLocation>
23652365
getEndCharLoc(const NodeTy *Node, const SourceManager &SM,
23662366
const LangOptions &LangOpts) {
2367-
unsigned TkLen = Lexer::MeasureTokenLength(Node->getEndLoc(), SM, LangOpts);
2368-
SourceLocation Loc = Node->getEndLoc().getLocWithOffset(TkLen - 1);
2369-
2370-
if (Loc.isValid())
2371-
return Loc;
2367+
if (unsigned TkLen =
2368+
Lexer::MeasureTokenLength(Node->getEndLoc(), SM, LangOpts)) {
2369+
SourceLocation Loc = Node->getEndLoc().getLocWithOffset(TkLen - 1);
23722370

2371+
if (Loc.isValid())
2372+
return Loc;
2373+
}
23732374
return std::nullopt;
23742375
}
23752376

clang/lib/CIR/CodeGen/Address.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@ class Address {
5252
elementType);
5353
}
5454

55+
Address(mlir::Value pointer, clang::CharUnits alignment)
56+
: Address(pointer,
57+
mlir::cast<cir::PointerType>(pointer.getType()).getPointee(),
58+
alignment) {
59+
assert((!alignment.isZero() || pointer == nullptr) &&
60+
"creating valid address with invalid alignment");
61+
}
62+
5563
static Address invalid() { return Address(nullptr); }
5664
bool isValid() const {
5765
return pointerAndKnownNonNull.getPointer() != nullptr;

clang/lib/CIR/CodeGen/CIRGenCall.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// These classes wrap the information about a call or function
10+
// definition used to handle ABI compliancy.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef CLANG_LIB_CODEGEN_CIRGENCALL_H
15+
#define CLANG_LIB_CODEGEN_CIRGENCALL_H
16+
17+
#include "clang/AST/GlobalDecl.h"
18+
#include "llvm/ADT/SmallVector.h"
19+
20+
namespace clang::CIRGen {
21+
22+
/// Type for representing both the decl and type of parameters to a function.
23+
/// The decl must be either a ParmVarDecl or ImplicitParamDecl.
24+
class FunctionArgList : public llvm::SmallVector<const clang::VarDecl *, 16> {};
25+
26+
} // namespace clang::CIRGen
27+
28+
#endif // CLANG_LIB_CODEGEN_CIRGENCALL_H

clang/lib/CIR/CodeGen/CIRGenDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ void CIRGenFunction::emitAutoVarAlloca(const VarDecl &d) {
4444
mlir::Type allocaTy = convertTypeForMem(ty);
4545
// Create the temp alloca and declare variable using it.
4646
address = createTempAlloca(allocaTy, alignment, loc, d.getName());
47-
declare(address, &d, ty, getLoc(d.getSourceRange()), alignment);
47+
declare(address.getPointer(), &d, ty, getLoc(d.getSourceRange()), alignment);
4848

4949
setAddrOfLocalVar(&d, address);
5050
}

clang/lib/CIR/CodeGen/CIRGenFunction.cpp

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
#include "CIRGenFunction.h"
1414

15+
#include "CIRGenCall.h"
16+
#include "mlir/IR/Location.h"
1517
#include "clang/AST/GlobalDecl.h"
1618
#include "clang/CIR/MissingFeatures.h"
1719

@@ -132,15 +134,17 @@ mlir::Location CIRGenFunction::getLoc(mlir::Location lhs, mlir::Location rhs) {
132134
return mlir::FusedLoc::get(locs, metadata, &getMLIRContext());
133135
}
134136

135-
mlir::LogicalResult CIRGenFunction::declare(Address addr, const Decl *var,
136-
QualType ty, mlir::Location loc,
137-
CharUnits alignment) {
137+
mlir::LogicalResult CIRGenFunction::declare(mlir::Value addrVal,
138+
const Decl *var, QualType ty,
139+
mlir::Location loc,
140+
CharUnits alignment, bool isParam) {
138141
const auto *namedVar = dyn_cast_or_null<NamedDecl>(var);
139142
assert(namedVar && "Needs a named decl");
140143
assert(!cir::MissingFeatures::cgfSymbolTable());
141144

142-
mlir::Value addrVal = addr.getPointer();
143145
auto allocaOp = cast<cir::AllocaOp>(addrVal.getDefiningOp());
146+
if (isParam)
147+
allocaOp.setInitAttr(mlir::UnitAttr::get(&getMLIRContext()));
144148
if (ty->isReferenceType() || ty.isConstQualified())
145149
allocaOp.setConstantAttr(mlir::UnitAttr::get(&getMLIRContext()));
146150

@@ -149,16 +153,49 @@ mlir::LogicalResult CIRGenFunction::declare(Address addr, const Decl *var,
149153

150154
void CIRGenFunction::startFunction(GlobalDecl gd, QualType returnType,
151155
cir::FuncOp fn, cir::FuncType funcType,
152-
SourceLocation loc,
156+
FunctionArgList args, SourceLocation loc,
153157
SourceLocation startLoc) {
154158
assert(!curFn &&
155159
"CIRGenFunction can only be used for one function at a time");
156160

157161
fnRetTy = returnType;
158162
curFn = fn;
159163

164+
const auto *fd = dyn_cast_or_null<FunctionDecl>(gd.getDecl());
165+
160166
mlir::Block *entryBB = &fn.getBlocks().front();
161167
builder.setInsertionPointToStart(entryBB);
168+
169+
// TODO(cir): this should live in `emitFunctionProlog
170+
// Declare all the function arguments in the symbol table.
171+
for (const auto nameValue : llvm::zip(args, entryBB->getArguments())) {
172+
const VarDecl *paramVar = std::get<0>(nameValue);
173+
mlir::Value paramVal = std::get<1>(nameValue);
174+
CharUnits alignment = getContext().getDeclAlign(paramVar);
175+
mlir::Location paramLoc = getLoc(paramVar->getSourceRange());
176+
paramVal.setLoc(paramLoc);
177+
178+
mlir::Value addrVal =
179+
emitAlloca(cast<NamedDecl>(paramVar)->getName(),
180+
convertType(paramVar->getType()), paramLoc, alignment);
181+
182+
declare(addrVal, paramVar, paramVar->getType(), paramLoc, alignment,
183+
/*isParam=*/true);
184+
185+
setAddrOfLocalVar(paramVar, Address(addrVal, alignment));
186+
187+
bool isPromoted = isa<ParmVarDecl>(paramVar) &&
188+
cast<ParmVarDecl>(paramVar)->isKNRPromoted();
189+
assert(!cir::MissingFeatures::constructABIArgDirectExtend());
190+
if (isPromoted)
191+
cgm.errorNYI(fd->getSourceRange(), "Function argument demotion");
192+
193+
// Location of the store to the param storage tracked as beginning of
194+
// the function body.
195+
mlir::Location fnBodyBegin = getLoc(fd->getBody()->getBeginLoc());
196+
builder.CIRBaseBuilderTy::createStore(fnBodyBegin, paramVal, addrVal);
197+
}
198+
assert(builder.getInsertionBlock() && "Should be valid");
162199
}
163200

164201
void CIRGenFunction::finishFunction(SourceLocation endLoc) {}
@@ -187,8 +224,10 @@ cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
187224
// This will be used once more code is upstreamed.
188225
[[maybe_unused]] mlir::Block *entryBB = fn.addEntryBlock();
189226

190-
startFunction(gd, funcDecl->getReturnType(), fn, funcType, loc,
191-
bodyRange.getBegin());
227+
FunctionArgList args;
228+
QualType retTy = buildFunctionArgList(gd, args);
229+
230+
startFunction(gd, retTy, fn, funcType, args, loc, bodyRange.getBegin());
192231

193232
if (isa<CXXDestructorDecl>(funcDecl))
194233
getCIRGenModule().errorNYI(bodyRange, "C++ destructor definition");
@@ -234,6 +273,29 @@ cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
234273
return fn;
235274
}
236275

276+
clang::QualType CIRGenFunction::buildFunctionArgList(clang::GlobalDecl gd,
277+
FunctionArgList &args) {
278+
const auto *fd = cast<FunctionDecl>(gd.getDecl());
279+
QualType retTy = fd->getReturnType();
280+
281+
const auto *md = dyn_cast<CXXMethodDecl>(fd);
282+
if (md && md->isInstance())
283+
cgm.errorNYI(fd->getSourceRange(), "buildFunctionArgList: CXXMethodDecl");
284+
285+
if (isa<CXXConstructorDecl>(fd))
286+
cgm.errorNYI(fd->getSourceRange(),
287+
"buildFunctionArgList: CXXConstructorDecl");
288+
289+
for (auto *param : fd->parameters())
290+
args.push_back(param);
291+
292+
if (md && (isa<CXXConstructorDecl>(md) || isa<CXXDestructorDecl>(md)))
293+
cgm.errorNYI(fd->getSourceRange(),
294+
"buildFunctionArgList: implicit structor params");
295+
296+
return retTy;
297+
}
298+
237299
/// Emit code to compute a designator that specifies the location
238300
/// of the expression.
239301
/// FIXME: document this function better.

clang/lib/CIR/CodeGen/CIRGenFunction.h

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

1616
#include "CIRGenBuilder.h"
17+
#include "CIRGenCall.h"
1718
#include "CIRGenModule.h"
1819
#include "CIRGenTypeCache.h"
1920
#include "CIRGenValue.h"
@@ -96,9 +97,9 @@ class CIRGenFunction : public CIRGenTypeCache {
9697
private:
9798
/// Declare a variable in the current scope, return success if the variable
9899
/// wasn't declared yet.
99-
mlir::LogicalResult declare(Address addr, const clang::Decl *var,
100+
mlir::LogicalResult declare(mlir::Value addrVal, const clang::Decl *var,
100101
clang::QualType ty, mlir::Location loc,
101-
clang::CharUnits alignment);
102+
clang::CharUnits alignment, bool isParam = false);
102103

103104
public:
104105
mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty,
@@ -196,12 +197,16 @@ class CIRGenFunction : public CIRGenTypeCache {
196197
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
197198
cir::FuncType funcType);
198199

200+
clang::QualType buildFunctionArgList(clang::GlobalDecl gd,
201+
FunctionArgList &args);
202+
199203
/// Emit code for the start of a function.
200204
/// \param loc The location to be associated with the function.
201205
/// \param startLoc The location of the function body.
202206
void startFunction(clang::GlobalDecl gd, clang::QualType retTy,
203207
cir::FuncOp fn, cir::FuncType funcType,
204-
clang::SourceLocation loc, clang::SourceLocation startLoc);
208+
FunctionArgList args, clang::SourceLocation loc,
209+
clang::SourceLocation startLoc);
205210

206211
Address createTempAlloca(mlir::Type ty, CharUnits align, mlir::Location loc,
207212
const Twine &name = "tmp");

0 commit comments

Comments
 (0)