Skip to content

Commit 8cf98f3

Browse files
Merge branch 'main' into uint_to_fp
2 parents d7809f2 + bc51a2e commit 8cf98f3

File tree

79 files changed

+1376
-719
lines changed

Some content is hidden

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

79 files changed

+1376
-719
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2776,7 +2776,7 @@ def Ownership : InheritableAttr {
27762776
let Args = [IdentifierArgument<"Module">,
27772777
VariadicParamIdxArgument<"Args">];
27782778
let Subjects = SubjectList<[HasFunctionProto]>;
2779-
let Documentation = [Undocumented];
2779+
let Documentation = [OwnershipDocs];
27802780
}
27812781

27822782
def Packed : InheritableAttr {

clang/include/clang/Basic/AttrDocs.td

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,6 +1389,81 @@ Query for this attribute with ``__has_attribute(overloadable)``.
13891389
}];
13901390
}
13911391

1392+
def OwnershipDocs : Documentation {
1393+
let Heading = "ownership_holds, ownership_returns, ownership_takes (Clang "
1394+
"Static Analyzer)";
1395+
let Category = DocCatFunction;
1396+
let Content = [{
1397+
1398+
.. note::
1399+
1400+
In order for the Clang Static Analyzer to acknowledge these attributes, the
1401+
``Optimistic`` config needs to be set to true for the checker
1402+
``unix.DynamicMemoryModeling``:
1403+
1404+
``-Xclang -analyzer-config -Xclang unix.DynamicMemoryModeling:Optimistic=true``
1405+
1406+
These attributes are used by the Clang Static Analyzer's dynamic memory modeling
1407+
facilities to mark custom allocating/deallocating functions.
1408+
1409+
All 3 attributes' first parameter of type string is the type of the allocation:
1410+
``malloc``, ``new``, etc. to allow for catching :ref:`mismatched deallocation
1411+
<unix-MismatchedDeallocator>` bugs. The allocation type can be any string, e.g.
1412+
a function annotated with
1413+
returning a piece of memory of type ``lasagna`` but freed with a function
1414+
annotated to release ``cheese`` typed memory will result in mismatched
1415+
deallocation warning.
1416+
1417+
The (currently) only allocation type having special meaning is ``malloc`` --
1418+
the Clang Static Analyzer makes sure that allocating functions annotated with
1419+
``malloc`` are treated like they used the standard ``malloc()``, and can be
1420+
safely deallocated with the standard ``free()``.
1421+
1422+
* Use ``ownership_returns`` to mark a function as an allocating function. Takes
1423+
1 parameter to denote the allocation type.
1424+
* Use ``ownership_takes`` to mark a function as a deallocating function. Takes 2
1425+
parameters: the allocation type, and the index of the parameter that is being
1426+
deallocated (counting from 1).
1427+
* Use ``ownership_holds`` to mark that a function takes over the ownership of a
1428+
piece of memory and will free it at some unspecified point in the future. Like
1429+
``ownership_takes``, this takes 2 parameters: the allocation type, and the
1430+
index of the parameter whose ownership will be taken over (counting from 1).
1431+
1432+
The annotations ``ownership_takes`` and ``ownership_holds`` both prevent memory
1433+
leak reports (concerning the specified argument); the difference between them
1434+
is that using taken memory is a use-after-free error, while using held memory
1435+
is assumed to be legitimate.
1436+
1437+
Example:
1438+
1439+
.. code-block:: c
1440+
1441+
// Denotes that my_malloc will return with a dynamically allocated piece of
1442+
// memory using malloc().
1443+
void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
1444+
1445+
// Denotes that my_free will deallocate its parameter using free().
1446+
void __attribute((ownership_takes(malloc, 1))) my_free(void *);
1447+
1448+
// Denotes that my_hold will take over the ownership of its parameter that was
1449+
// allocated via malloc().
1450+
void __attribute((ownership_holds(malloc, 1))) my_hold(void *);
1451+
1452+
Further reading about dynamic memory modeling in the Clang Static Analyzer is
1453+
found in these checker docs:
1454+
:ref:`unix.Malloc <unix-Malloc>`, :ref:`unix.MallocSizeof <unix-MallocSizeof>`,
1455+
:ref:`unix.MismatchedDeallocator <unix-MismatchedDeallocator>`,
1456+
:ref:`cplusplus.NewDelete <cplusplus-NewDelete>`,
1457+
:ref:`cplusplus.NewDeleteLeaks <cplusplus-NewDeleteLeaks>`,
1458+
:ref:`optin.taint.TaintedAlloc <optin-taint-TaintedAlloc>`.
1459+
Mind that many more checkers are affected by dynamic memory modeling changes to
1460+
some extent.
1461+
1462+
Further reading for other annotations:
1463+
`Source Annotations in the Clang Static Analyzer <https://clang-analyzer.llvm.org/annotations.html>`_.
1464+
}];
1465+
}
1466+
13921467
def ObjCMethodFamilyDocs : Documentation {
13931468
let Category = DocCatFunction;
13941469
let Content = [{

clang/include/clang/Basic/arm_sme.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,8 @@ let SMETargetGuard = "sme2" in {
716716
def SVZERO_ZT : Inst<"svzero_zt", "vi", "", MergeNone, "aarch64_sme_zero_zt", [IsOverloadNone, IsStreamingCompatible, IsOutZT0], [ImmCheck<0, ImmCheck0_0>]>;
717717
}
718718

719+
def IN_STREAMING_MODE : Inst<"__arm_in_streaming_mode", "sv", "Pc", MergeNone, "aarch64_sme_in_streaming_mode", [IsOverloadNone, IsStreamingCompatible], []>;
720+
719721
//
720722
// lookup table expand four contiguous registers
721723
//

clang/lib/AST/ASTContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14357,7 +14357,7 @@ QualType ASTContext::getCorrespondingSignedFixedPointType(QualType Ty) const {
1435714357
// corresponding backend features (which may contain duplicates).
1435814358
static std::vector<std::string> getFMVBackendFeaturesFor(
1435914359
const llvm::SmallVectorImpl<StringRef> &FMVFeatStrings) {
14360-
std::vector<std::string> BackendFeats{{"+fmv"}};
14360+
std::vector<std::string> BackendFeats;
1436114361
llvm::AArch64::ExtensionSet FeatureBits;
1436214362
for (StringRef F : FMVFeatStrings)
1436314363
if (auto FMVExt = llvm::AArch64::parseFMVExtension(F))

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11327,6 +11327,19 @@ Value *CodeGenFunction::EmitAArch64SMEBuiltinExpr(unsigned BuiltinID,
1132711327
if (Builtin->LLVMIntrinsic == 0)
1132811328
return nullptr;
1132911329

11330+
if (BuiltinID == SME::BI__builtin_sme___arm_in_streaming_mode) {
11331+
// If we already know the streaming mode, don't bother with the intrinsic
11332+
// and emit a constant instead
11333+
const auto *FD = cast<FunctionDecl>(CurFuncDecl);
11334+
if (const auto *FPT = FD->getType()->getAs<FunctionProtoType>()) {
11335+
unsigned SMEAttrs = FPT->getAArch64SMEAttributes();
11336+
if (!(SMEAttrs & FunctionType::SME_PStateSMCompatibleMask)) {
11337+
bool IsStreaming = SMEAttrs & FunctionType::SME_PStateSMEnabledMask;
11338+
return ConstantInt::getBool(Builder.getContext(), IsStreaming);
11339+
}
11340+
}
11341+
}
11342+
1133011343
// Predicates must match the main datatype.
1133111344
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
1133211345
if (auto PredTy = dyn_cast<llvm::VectorType>(Ops[i]->getType()))

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2748,7 +2748,21 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD,
27482748
Attrs.addAttribute("target-features", llvm::join(Features, ","));
27492749
AddedAttr = true;
27502750
}
2751-
2751+
if (getTarget().getTriple().isAArch64()) {
2752+
llvm::SmallVector<StringRef, 8> Feats;
2753+
if (TV)
2754+
TV->getFeatures(Feats);
2755+
else if (TC)
2756+
TC->getFeatures(Feats, GD.getMultiVersionIndex());
2757+
if (!Feats.empty()) {
2758+
llvm::sort(Feats);
2759+
std::string FMVFeatures;
2760+
for (StringRef F : Feats)
2761+
FMVFeatures.append(",+" + F.str());
2762+
Attrs.addAttribute("fmv-features", FMVFeatures.substr(1));
2763+
AddedAttr = true;
2764+
}
2765+
}
27522766
return AddedAttr;
27532767
}
27542768

clang/lib/CodeGen/Targets/SPIR.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class SPIRVTargetCodeGenInfo : public CommonSPIRTargetCodeGenInfo {
6464
void setCUDAKernelCallingConvention(const FunctionType *&FT) const override;
6565
LangAS getGlobalVarAddressSpace(CodeGenModule &CGM,
6666
const VarDecl *D) const override;
67+
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
68+
CodeGen::CodeGenModule &M) const override;
6769
llvm::SyncScope::ID getLLVMSyncScopeID(const LangOptions &LangOpts,
6870
SyncScope Scope,
6971
llvm::AtomicOrdering Ordering,
@@ -245,6 +247,41 @@ SPIRVTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM,
245247
return DefaultGlobalAS;
246248
}
247249

250+
void SPIRVTargetCodeGenInfo::setTargetAttributes(
251+
const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const {
252+
if (!M.getLangOpts().HIP ||
253+
M.getTarget().getTriple().getVendor() != llvm::Triple::AMD)
254+
return;
255+
if (GV->isDeclaration())
256+
return;
257+
258+
auto F = dyn_cast<llvm::Function>(GV);
259+
if (!F)
260+
return;
261+
262+
auto FD = dyn_cast_or_null<FunctionDecl>(D);
263+
if (!FD)
264+
return;
265+
if (!FD->hasAttr<CUDAGlobalAttr>())
266+
return;
267+
268+
unsigned N = M.getLangOpts().GPUMaxThreadsPerBlock;
269+
if (auto FlatWGS = FD->getAttr<AMDGPUFlatWorkGroupSizeAttr>())
270+
N = FlatWGS->getMax()->EvaluateKnownConstInt(M.getContext()).getExtValue();
271+
272+
// We encode the maximum flat WG size in the first component of the 3D
273+
// max_work_group_size attribute, which will get reverse translated into the
274+
// original AMDGPU attribute when targeting AMDGPU.
275+
auto Int32Ty = llvm::IntegerType::getInt32Ty(M.getLLVMContext());
276+
llvm::Metadata *AttrMDArgs[] = {
277+
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, N)),
278+
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 1)),
279+
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 1))};
280+
281+
F->setMetadata("max_work_group_size",
282+
llvm::MDNode::get(M.getLLVMContext(), AttrMDArgs));
283+
}
284+
248285
llvm::SyncScope::ID
249286
SPIRVTargetCodeGenInfo::getLLVMSyncScopeID(const LangOptions &, SyncScope Scope,
250287
llvm::AtomicOrdering,

clang/lib/Format/MatchFilePath.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@ bool matchFilePath(StringRef Pattern, StringRef FilePath) {
6363
if (I == EOP) // `Pattern` ends with a star.
6464
return Globstar || NoMoreSeparatorsInFilePath;
6565
if (Pattern[I] != Separator) {
66-
Globstar = false;
6766
// `Pattern` ends with a lone backslash.
6867
if (Pattern[I] == '\\' && ++I == EOP)
6968
return false;
69+
Globstar = false;
7070
}
7171
// The star is followed by a (possibly escaped) `Separator`.
7272
if (Pattern[I] == Separator) {

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,6 @@ class AnnotatingParser {
137137
private:
138138
ScopeType getScopeType(const FormatToken &Token) const {
139139
switch (Token.getType()) {
140-
case TT_LambdaLBrace:
141-
return ST_ChildBlock;
142140
case TT_ClassLBrace:
143141
case TT_StructLBrace:
144142
case TT_UnionLBrace:
@@ -3395,13 +3393,13 @@ class ExpressionParser {
33953393
/// Parse unary operator expressions and surround them with fake
33963394
/// parentheses if appropriate.
33973395
void parseUnaryOperator() {
3398-
llvm::SmallVector<FormatToken *, 2> Tokens;
3396+
SmallVector<FormatToken *, 2> Tokens;
33993397
while (Current && Current->is(TT_UnaryOperator)) {
34003398
Tokens.push_back(Current);
34013399
next();
34023400
}
34033401
parse(PrecedenceArrowAndPeriod);
3404-
for (FormatToken *Token : llvm::reverse(Tokens)) {
3402+
for (FormatToken *Token : reverse(Tokens)) {
34053403
// The actual precedence doesn't matter.
34063404
addFakeParenthesis(Token, prec::Unknown);
34073405
}
@@ -3579,7 +3577,7 @@ class ExpressionParser {
35793577
void TokenAnnotator::setCommentLineLevels(
35803578
SmallVectorImpl<AnnotatedLine *> &Lines) const {
35813579
const AnnotatedLine *NextNonCommentLine = nullptr;
3582-
for (AnnotatedLine *Line : llvm::reverse(Lines)) {
3580+
for (AnnotatedLine *Line : reverse(Lines)) {
35833581
assert(Line->First);
35843582

35853583
// If the comment is currently aligned with the line immediately following
@@ -3700,7 +3698,7 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) {
37003698
Line.Type = Parser.parseLine();
37013699

37023700
if (!Line.Children.empty()) {
3703-
ScopeStack.push_back(ST_ChildBlock);
3701+
ScopeStack.push_back(ST_Other);
37043702
const bool InRequiresExpression = Line.Type == LT_RequiresExpression;
37053703
for (auto &Child : Line.Children) {
37063704
if (InRequiresExpression &&

clang/lib/Format/TokenAnnotator.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,11 @@ enum LineType {
3838
};
3939

4040
enum ScopeType {
41-
// Contained in child block.
42-
ST_ChildBlock,
4341
// Contained in class declaration/definition.
4442
ST_Class,
4543
// Contained in compound requirement.
4644
ST_CompoundRequirement,
47-
// Contained within other scope block (function, loop, if/else, etc).
45+
// Contained in other blocks (function, lambda, loop, if/else, child, etc).
4846
ST_Other,
4947
};
5048

0 commit comments

Comments
 (0)