Skip to content

Commit 6bbc95a

Browse files
authored
merge main into amd-staging (llvm#3917)
2 parents adab372 + 87fbace commit 6bbc95a

File tree

25 files changed

+285
-216
lines changed

25 files changed

+285
-216
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@ Bug Fixes to C++ Support
588588
- Fix the parsing of variadic member functions when the ellipis immediately follows a default argument.(#GH153445)
589589
- Fixed a bug that caused ``this`` captured by value in a lambda with a dependent explicit object parameter to not be
590590
instantiated properly. (#GH154054)
591+
- Fixed a bug where our ``member-like constrained friend`` checking caused an incorrect analysis of lambda captures. (#GH156225)
591592
- Fixed a crash when implicit conversions from initialize list to arrays of
592593
unknown bound during constant evaluation. (#GH151716)
593594

clang/lib/AST/DynamicRecursiveASTVisitor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ using namespace clang;
8787
// ends up executing RAV's implementation because we used a qualified
8888
// function call.
8989
//
90-
// End result: RAV::TraverseCallExpr() is executed,
90+
// End result: RAV::TraverseCallExpr() is executed.
9191
namespace {
9292
template <bool Const> struct Impl : RecursiveASTVisitor<Impl<Const>> {
9393
DynamicRecursiveASTVisitorBase<Const> &Visitor;

clang/lib/Basic/Builtins.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ static bool builtinIsSupported(const llvm::StringTable &Strings,
165165
/* OpenCLC Unsupported */
166166
if (!LangOpts.OpenCL && (BuiltinInfo.Langs & ALL_OCL_LANGUAGES))
167167
return false;
168-
/* OopenCL GAS Unsupported */
168+
/* OpenCL GAS Unsupported */
169169
if (!LangOpts.OpenCLGenericAddressSpace && (BuiltinInfo.Langs & OCL_GAS))
170170
return false;
171171
/* OpenCL Pipe Unsupported */

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,79 +1716,98 @@ NamedDecl *Sema::ActOnTemplateTemplateParameter(
17161716

17171717
namespace {
17181718
class ConstraintRefersToContainingTemplateChecker
1719-
: public TreeTransform<ConstraintRefersToContainingTemplateChecker> {
1719+
: public ConstDynamicRecursiveASTVisitor {
1720+
using inherited = ConstDynamicRecursiveASTVisitor;
17201721
bool Result = false;
17211722
const FunctionDecl *Friend = nullptr;
17221723
unsigned TemplateDepth = 0;
17231724

17241725
// Check a record-decl that we've seen to see if it is a lexical parent of the
17251726
// Friend, likely because it was referred to without its template arguments.
1726-
void CheckIfContainingRecord(const CXXRecordDecl *CheckingRD) {
1727+
bool CheckIfContainingRecord(const CXXRecordDecl *CheckingRD) {
17271728
CheckingRD = CheckingRD->getMostRecentDecl();
17281729
if (!CheckingRD->isTemplated())
1729-
return;
1730+
return true;
17301731

17311732
for (const DeclContext *DC = Friend->getLexicalDeclContext();
17321733
DC && !DC->isFileContext(); DC = DC->getParent())
17331734
if (const auto *RD = dyn_cast<CXXRecordDecl>(DC))
1734-
if (CheckingRD == RD->getMostRecentDecl())
1735+
if (CheckingRD == RD->getMostRecentDecl()) {
17351736
Result = true;
1737+
return false;
1738+
}
1739+
1740+
return true;
17361741
}
17371742

1738-
void CheckNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
1743+
bool CheckNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
17391744
if (D->getDepth() < TemplateDepth)
17401745
Result = true;
17411746

17421747
// Necessary because the type of the NTTP might be what refers to the parent
17431748
// constriant.
1744-
TransformType(D->getType());
1749+
return TraverseType(D->getType());
17451750
}
17461751

17471752
public:
1748-
using inherited = TreeTransform<ConstraintRefersToContainingTemplateChecker>;
1749-
1750-
ConstraintRefersToContainingTemplateChecker(Sema &SemaRef,
1751-
const FunctionDecl *Friend,
1753+
ConstraintRefersToContainingTemplateChecker(const FunctionDecl *Friend,
17521754
unsigned TemplateDepth)
1753-
: inherited(SemaRef), Friend(Friend), TemplateDepth(TemplateDepth) {}
1755+
: Friend(Friend), TemplateDepth(TemplateDepth) {}
1756+
17541757
bool getResult() const { return Result; }
17551758

17561759
// This should be the only template parm type that we have to deal with.
1757-
// SubstTempalteTypeParmPack, SubstNonTypeTemplateParmPack, and
1760+
// SubstTemplateTypeParmPack, SubstNonTypeTemplateParmPack, and
17581761
// FunctionParmPackExpr are all partially substituted, which cannot happen
17591762
// with concepts at this point in translation.
1760-
using inherited::TransformTemplateTypeParmType;
1761-
QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
1762-
TemplateTypeParmTypeLoc TL, bool) {
1763-
if (TL.getDecl()->getDepth() < TemplateDepth)
1763+
bool VisitTemplateTypeParmType(const TemplateTypeParmType *Type) override {
1764+
if (Type->getDecl()->getDepth() < TemplateDepth) {
17641765
Result = true;
1765-
return inherited::TransformTemplateTypeParmType(
1766-
TLB, TL,
1767-
/*SuppressObjCLifetime=*/false);
1766+
return false;
1767+
}
1768+
return true;
17681769
}
17691770

1770-
Decl *TransformDecl(SourceLocation Loc, Decl *D) {
1771-
if (!D)
1772-
return D;
1771+
bool TraverseDeclRefExpr(const DeclRefExpr *E) override {
1772+
return TraverseDecl(E->getDecl());
1773+
}
1774+
1775+
bool TraverseTypedefType(const TypedefType *TT,
1776+
bool /*TraverseQualifier*/) override {
1777+
return TraverseType(TT->desugar());
1778+
}
1779+
1780+
bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier) override {
1781+
// We don't care about TypeLocs. So traverse Types instead.
1782+
return TraverseType(TL.getType(), TraverseQualifier);
1783+
}
1784+
1785+
bool VisitTagType(const TagType *T) override {
1786+
return TraverseDecl(T->getOriginalDecl());
1787+
}
1788+
1789+
bool TraverseDecl(const Decl *D) override {
1790+
assert(D);
17731791
// FIXME : This is possibly an incomplete list, but it is unclear what other
17741792
// Decl kinds could be used to refer to the template parameters. This is a
17751793
// best guess so far based on examples currently available, but the
17761794
// unreachable should catch future instances/cases.
17771795
if (auto *TD = dyn_cast<TypedefNameDecl>(D))
1778-
TransformType(TD->getUnderlyingType());
1779-
else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(D))
1780-
CheckNonTypeTemplateParmDecl(NTTPD);
1781-
else if (auto *VD = dyn_cast<ValueDecl>(D))
1782-
TransformType(VD->getType());
1783-
else if (auto *TD = dyn_cast<TemplateDecl>(D))
1784-
TransformTemplateParameterList(TD->getTemplateParameters());
1785-
else if (auto *RD = dyn_cast<CXXRecordDecl>(D))
1786-
CheckIfContainingRecord(RD);
1787-
else if (isa<NamedDecl>(D)) {
1796+
return TraverseType(TD->getUnderlyingType());
1797+
if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(D))
1798+
return CheckNonTypeTemplateParmDecl(NTTPD);
1799+
if (auto *VD = dyn_cast<ValueDecl>(D))
1800+
return TraverseType(VD->getType());
1801+
if (isa<TemplateDecl>(D))
1802+
return true;
1803+
if (auto *RD = dyn_cast<CXXRecordDecl>(D))
1804+
return CheckIfContainingRecord(RD);
1805+
1806+
if (isa<NamedDecl, RequiresExprBodyDecl>(D)) {
17881807
// No direct types to visit here I believe.
17891808
} else
17901809
llvm_unreachable("Don't know how to handle this declaration type yet");
1791-
return D;
1810+
return true;
17921811
}
17931812
};
17941813
} // namespace
@@ -1797,9 +1816,8 @@ bool Sema::ConstraintExpressionDependsOnEnclosingTemplate(
17971816
const FunctionDecl *Friend, unsigned TemplateDepth,
17981817
const Expr *Constraint) {
17991818
assert(Friend->getFriendObjectKind() && "Only works on a friend");
1800-
ConstraintRefersToContainingTemplateChecker Checker(*this, Friend,
1801-
TemplateDepth);
1802-
Checker.TransformExpr(const_cast<Expr *>(Constraint));
1819+
ConstraintRefersToContainingTemplateChecker Checker(Friend, TemplateDepth);
1820+
Checker.TraverseStmt(Constraint);
18031821
return Checker.getResult();
18041822
}
18051823

clang/test/SemaTemplate/concepts-friends.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,3 +548,21 @@ Template<void, 4> f{};
548548
static_assert(+Template<float, 5>{} == 5);
549549

550550
} // namespace GH78101
551+
552+
namespace GH156225 {
553+
554+
struct Test {
555+
template <class T>
556+
friend constexpr bool foo()
557+
requires([] {
558+
bool flags[1];
559+
for (bool x : flags)
560+
return false;
561+
return true;
562+
}())
563+
{
564+
return {};
565+
}
566+
};
567+
568+
}

compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,12 @@ struct sanitizer_kernel_sockaddr {
143143
char sa_data[14];
144144
};
145145

146+
struct sanitizer_kernel_open_how {
147+
u64 flags;
148+
u64 mode;
149+
u64 resolve;
150+
};
151+
146152
// Real sigset size is always passed as a syscall argument.
147153
// Declare it "void" to catch sizeof(kernel_sigset_t).
148154
typedef void kernel_sigset_t;
@@ -2843,6 +2849,18 @@ PRE_SYSCALL(openat)(long dfd, const void *filename, long flags, long mode) {
28432849
POST_SYSCALL(openat)
28442850
(long res, long dfd, const void *filename, long flags, long mode) {}
28452851

2852+
PRE_SYSCALL(openat2)(long dfd, const void* filename,
2853+
const sanitizer_kernel_open_how* how, uptr howlen) {
2854+
if (filename)
2855+
PRE_READ(filename, __sanitizer::internal_strlen((const char*)filename) + 1);
2856+
2857+
if (how)
2858+
PRE_READ(how, howlen);
2859+
}
2860+
2861+
POST_SYSCALL(openat2)(long res, long dfd, const void* filename,
2862+
const sanitizer_kernel_open_how* how, uptr howlen) {}
2863+
28462864
PRE_SYSCALL(newfstatat)
28472865
(long dfd, const void *filename, void *statbuf, long flag) {
28482866
if (filename)

llvm/include/llvm/Analysis/MemoryProfileInfo.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ LLVM_ABI std::string getAllocTypeAttributeString(AllocationType Type);
5959
/// True if the AllocTypes bitmask contains just a single type.
6060
LLVM_ABI bool hasSingleAllocType(uint8_t AllocTypes);
6161

62+
/// Removes any existing "ambiguous" memprof attribute. Called before we apply a
63+
/// specific allocation type such as "cold", "notcold", or "hot".
64+
LLVM_ABI void removeAnyExistingAmbiguousAttribute(CallBase *CB);
65+
66+
/// Adds an "ambiguous" memprof attribute to call with a matched allocation
67+
/// profile but that we haven't yet been able to disambiguate.
68+
LLVM_ABI void addAmbiguousAttribute(CallBase *CB);
69+
6270
/// Class to build a trie of call stack contexts for a particular profiled
6371
/// allocation call, along with their associated allocation types.
6472
/// The allocation will be at the root of the trie, which is then used to

llvm/include/llvm/IR/RuntimeLibcalls.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ def AEABI_MEMCLR8 : RuntimeLibcall;
446446

447447
// Hexagon calls
448448
def HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES : RuntimeLibcall;
449+
def HEXAGON_VOLATILE_MEMCPY : RuntimeLibcall;
449450

450451
// XCore calls
451452
def MEMCPY_ALIGN_4 : RuntimeLibcall;
@@ -1875,6 +1876,8 @@ def __hexagon_fast2_sqrtdf2 : RuntimeLibcallImpl<FAST_SQRT_F64>;
18751876

18761877
def __hexagon_memcpy_likely_aligned_min32bytes_mult8bytes
18771878
: RuntimeLibcallImpl<HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES>;
1879+
1880+
def hexagon_memcpy_forward_vp4cp4n2 : RuntimeLibcallImpl<HEXAGON_VOLATILE_MEMCPY>;
18781881
}
18791882

18801883
def isHexagon : RuntimeLibcallPredicate<"TT.getArch() == Triple::hexagon">;

llvm/include/llvm/Linker/IRMover.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define LLVM_LINKER_IRMOVER_H
1111

1212
#include "llvm/ADT/ArrayRef.h"
13+
#include "llvm/ADT/DenseMap.h"
1314
#include "llvm/ADT/DenseSet.h"
1415
#include "llvm/ADT/FunctionExtras.h"
1516
#include "llvm/Support/Compiler.h"
@@ -19,6 +20,8 @@ namespace llvm {
1920
class Error;
2021
class GlobalValue;
2122
class Metadata;
23+
class MDNode;
24+
class NamedMDNode;
2225
class Module;
2326
class StructType;
2427
class TrackingMDRef;
@@ -67,6 +70,8 @@ class IRMover {
6770
using LazyCallback =
6871
llvm::unique_function<void(GlobalValue &GV, ValueAdder Add)>;
6972

73+
using NamedMDNodesT = DenseMap<const NamedMDNode *, DenseSet<const MDNode *>>;
74+
7075
/// Move in the provide values in \p ValuesToLink from \p Src.
7176
///
7277
/// - \p AddLazyFor is a call back that the IRMover will call when a global
@@ -86,6 +91,7 @@ class IRMover {
8691
Module &Composite;
8792
IdentifiedStructTypeSet IdentifiedStructTypes;
8893
MDMapT SharedMDs; ///< A Metadata map to use for all calls to \a move().
94+
NamedMDNodesT NamedMDNodes; ///< Cache for IRMover::linkNamedMDNodes().
8995
};
9096

9197
} // End llvm namespace

llvm/lib/Analysis/MemoryProfileInfo.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,24 @@ bool llvm::memprof::hasSingleAllocType(uint8_t AllocTypes) {
121121
return NumAllocTypes == 1;
122122
}
123123

124+
void llvm::memprof::removeAnyExistingAmbiguousAttribute(CallBase *CB) {
125+
if (!CB->hasFnAttr("memprof"))
126+
return;
127+
assert(CB->getFnAttr("memprof").getValueAsString() == "ambiguous");
128+
CB->removeFnAttr("memprof");
129+
}
130+
131+
void llvm::memprof::addAmbiguousAttribute(CallBase *CB) {
132+
// We may have an existing ambiguous attribute if we are reanalyzing
133+
// after inlining.
134+
if (CB->hasFnAttr("memprof")) {
135+
assert(CB->getFnAttr("memprof").getValueAsString() == "ambiguous");
136+
} else {
137+
auto A = llvm::Attribute::get(CB->getContext(), "memprof", "ambiguous");
138+
CB->addFnAttr(A);
139+
}
140+
}
141+
124142
void CallStackTrie::addCallStack(
125143
AllocationType AllocType, ArrayRef<uint64_t> StackIds,
126144
std::vector<ContextTotalSize> ContextSizeInfo) {
@@ -466,6 +484,9 @@ void CallStackTrie::addSingleAllocTypeAttribute(CallBase *CI, AllocationType AT,
466484
StringRef Descriptor) {
467485
auto AllocTypeString = getAllocTypeAttributeString(AT);
468486
auto A = llvm::Attribute::get(CI->getContext(), "memprof", AllocTypeString);
487+
// After inlining we may be able to convert an existing ambiguous allocation
488+
// to an unambiguous one.
489+
removeAnyExistingAmbiguousAttribute(CI);
469490
CI->addFnAttr(A);
470491
if (MemProfReportHintedSizes) {
471492
std::vector<ContextTotalSize> ContextSizeInfo;
@@ -525,6 +546,7 @@ bool CallStackTrie::buildAndAttachMIBMetadata(CallBase *CI) {
525546
assert(MIBCallStack.size() == 1 &&
526547
"Should only be left with Alloc's location in stack");
527548
CI->setMetadata(LLVMContext::MD_memprof, MDNode::get(Ctx, MIBNodes));
549+
addAmbiguousAttribute(CI);
528550
return true;
529551
}
530552
// If there exists corner case that CallStackTrie has one chain to leaf

0 commit comments

Comments
 (0)