Skip to content

Commit 9b007be

Browse files
SC llvm teamSC llvm team
SC llvm team
authored and
SC llvm team
committed
Merged main:175aa864f33786f3a6a4ee7381cbcafd0758501a into amd-gfx:ad92d65754df
Local branch amd-gfx ad92d65 Merged main:6ae657b08d624f9634fa6ebbf5d6fd7a22dc3b4d into amd-gfx:57a9efc3a4ac Remote branch main 175aa86 [LoongArch] Format LoongArchL{A}SXInstrInfo.td. NFC
2 parents ad92d65 + 175aa86 commit 9b007be

File tree

61 files changed

+792
-429
lines changed

Some content is hidden

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

61 files changed

+792
-429
lines changed

.github/workflows/release-asset-audit.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
import github
22
import sys
33

4+
_SPECIAL_CASE_BINARIES = {
5+
"keith": {"clang+llvm-18.1.8-arm64-apple-macos11.tar.xz"},
6+
}
7+
8+
9+
def _is_valid(uploader_name, valid_uploaders, asset_name):
10+
if uploader_name in valid_uploaders:
11+
return True
12+
13+
if uploader_name in _SPECIAL_CASE_BINARIES:
14+
return asset_name in _SPECIAL_CASE_BINARIES[uploader_name]
15+
16+
return False
17+
18+
419
def main():
520
token = sys.argv[1]
621

@@ -41,7 +56,7 @@ def main():
4156
print(
4257
f"{asset.name} : {asset.uploader.login} [{created_at} {updated_at}] ( {asset.download_count} )"
4358
)
44-
if asset.uploader.login not in uploaders:
59+
if not _is_valid(asset.uploader.login, uploaders, asset.name):
4560
with open('comment', 'w') as file:
4661
file.write(f'@{asset.uploader.login} is not a valid uploader.')
4762
sys.exit(1)

clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,10 @@ class ExprEngine {
286286
const Stmt *DiagnosticStmt = nullptr,
287287
ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind);
288288

289+
/// A tag to track convenience transitions, which can be removed at cleanup.
290+
/// This tag applies to a node created after removeDead.
291+
static const ProgramPointTag *cleanupNodeTag();
292+
289293
/// processCFGElement - Called by CoreEngine. Used to generate new successor
290294
/// nodes by processing the 'effects' of a CFG element.
291295
void processCFGElement(const CFGElement E, ExplodedNode *Pred,

clang/lib/AST/ComputeDependence.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ ExprDependence clang::computeDependence(BinaryOperator *E) {
164164
ExprDependence clang::computeDependence(ConditionalOperator *E) {
165165
// The type of the conditional operator depends on the type of the conditional
166166
// to support the GCC vector conditional extension. Additionally,
167-
// [temp.dep.expr] does specify state that this should be dependent on ALL sub
167+
// [temp.dep.expr] does specify that this should be dependent on ALL sub
168168
// expressions.
169169
return E->getCond()->getDependence() | E->getLHS()->getDependence() |
170170
E->getRHS()->getDependence();

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4732,7 +4732,9 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
47324732
Left.isOneOf(tok::kw_new, tok::kw_delete) &&
47334733
Right.isNot(TT_OverloadedOperatorLParen) &&
47344734
!(Line.MightBeFunctionDecl && Left.is(TT_FunctionDeclarationName))) {
4735-
return Style.SpaceBeforeParensOptions.AfterPlacementOperator;
4735+
const auto *RParen = Right.MatchingParen;
4736+
return Style.SpaceBeforeParensOptions.AfterPlacementOperator ||
4737+
(RParen && RParen->is(TT_CastRParen));
47364738
}
47374739
if (Line.Type == LT_ObjCDecl)
47384740
return true;

clang/lib/Format/WhitespaceManager.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,9 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
469469
// except if the token is equal, then a space is needed.
470470
if ((Style.PointerAlignment == FormatStyle::PAS_Right ||
471471
Style.ReferenceAlignment == FormatStyle::RAS_Right) &&
472-
CurrentChange.Spaces != 0 && CurrentChange.Tok->isNot(tok::equal)) {
472+
CurrentChange.Spaces != 0 &&
473+
!CurrentChange.Tok->isOneOf(tok::equal, tok::r_paren,
474+
TT_TemplateCloser)) {
473475
const bool ReferenceNotRightAligned =
474476
Style.ReferenceAlignment != FormatStyle::RAS_Right &&
475477
Style.ReferenceAlignment != FormatStyle::RAS_Pointer;

clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,14 @@ static const MemSpaceRegion *getStackOrGlobalSpaceRegion(const MemRegion *R) {
305305
return nullptr;
306306
}
307307

308+
const MemRegion *getOriginBaseRegion(const MemRegion *Reg) {
309+
Reg = Reg->getBaseRegion();
310+
while (const auto *SymReg = dyn_cast<SymbolicRegion>(Reg)) {
311+
Reg = SymReg->getSymbol()->getOriginRegion()->getBaseRegion();
312+
}
313+
return Reg;
314+
}
315+
308316
std::optional<std::string> printReferrer(const MemRegion *Referrer) {
309317
assert(Referrer);
310318
const StringRef ReferrerMemorySpace = [](const MemSpaceRegion *Space) {
@@ -313,7 +321,8 @@ std::optional<std::string> printReferrer(const MemRegion *Referrer) {
313321
if (isa<GlobalsSpaceRegion>(Space))
314322
return "global";
315323
assert(isa<StackSpaceRegion>(Space));
316-
return "stack";
324+
// This case covers top-level and inlined analyses.
325+
return "caller";
317326
}(getStackOrGlobalSpaceRegion(Referrer));
318327

319328
while (!Referrer->canPrintPretty()) {
@@ -340,19 +349,45 @@ std::optional<std::string> printReferrer(const MemRegion *Referrer) {
340349
return buf;
341350
}
342351

352+
/// Check whether \p Region refers to a freshly minted symbol after an opaque
353+
/// function call.
354+
bool isInvalidatedSymbolRegion(const MemRegion *Region) {
355+
const auto *SymReg = Region->getAs<SymbolicRegion>();
356+
if (!SymReg)
357+
return false;
358+
SymbolRef Symbol = SymReg->getSymbol();
359+
360+
const auto *DerS = dyn_cast<SymbolDerived>(Symbol);
361+
return DerS && isa_and_nonnull<SymbolConjured>(DerS->getParentSymbol());
362+
}
363+
343364
void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS,
344365
CheckerContext &Ctx) const {
345366
if (!ChecksEnabled[CK_StackAddrEscapeChecker])
346367
return;
347368

348369
ExplodedNode *Node = Ctx.getPredecessor();
349370

371+
bool ExitingTopFrame =
372+
Ctx.getPredecessor()->getLocationContext()->inTopFrame();
373+
374+
if (ExitingTopFrame &&
375+
Node->getLocation().getTag() == ExprEngine::cleanupNodeTag() &&
376+
Node->getFirstPred()) {
377+
// When finishing analysis of a top-level function, engine proactively
378+
// removes dead symbols thus preventing this checker from looking through
379+
// the output parameters. Take 1 step back, to the node where these symbols
380+
// and their bindings are still present
381+
Node = Node->getFirstPred();
382+
}
383+
350384
// Iterate over all bindings to global variables and see if it contains
351385
// a memory region in the stack space.
352386
class CallBack : public StoreManager::BindingsHandler {
353387
private:
354388
CheckerContext &Ctx;
355389
const StackFrameContext *PoppedFrame;
390+
const bool TopFrame;
356391

357392
/// Look for stack variables referring to popped stack variables.
358393
/// Returns true only if it found some dangling stack variables
@@ -368,24 +403,51 @@ void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS,
368403

369404
const auto *ReferrerStackSpace =
370405
ReferrerMemSpace->getAs<StackSpaceRegion>();
406+
371407
if (!ReferrerStackSpace)
372408
return false;
373409

374-
if (ReferredMemSpace->getStackFrame() == PoppedFrame &&
375-
ReferrerStackSpace->getStackFrame()->isParentOf(PoppedFrame)) {
410+
if (const auto *ReferredFrame = ReferredMemSpace->getStackFrame();
411+
ReferredFrame != PoppedFrame) {
412+
return false;
413+
}
414+
415+
if (ReferrerStackSpace->getStackFrame()->isParentOf(PoppedFrame)) {
416+
V.emplace_back(Referrer, Referred);
417+
return true;
418+
}
419+
if (isa<StackArgumentsSpaceRegion>(ReferrerMemSpace) &&
420+
ReferrerStackSpace->getStackFrame() == PoppedFrame && TopFrame) {
421+
// Output parameter of a top-level function
376422
V.emplace_back(Referrer, Referred);
377423
return true;
378424
}
379425
return false;
380426
}
381427

428+
// Keep track of the variables that were invalidated through an opaque
429+
// function call. Even if the initial values of such variables were bound to
430+
// an address of a local variable, we cannot claim anything now, at the
431+
// function exit, so skip them to avoid false positives.
432+
void recordInInvalidatedRegions(const MemRegion *Region) {
433+
if (isInvalidatedSymbolRegion(Region))
434+
ExcludedRegions.insert(getOriginBaseRegion(Region));
435+
}
436+
382437
public:
383438
SmallVector<std::pair<const MemRegion *, const MemRegion *>, 10> V;
439+
// ExcludedRegions are skipped from reporting.
440+
// I.e., if a referrer in this set, skip the related bug report.
441+
// It is useful to avoid false positive for the variables that were
442+
// reset to a conjured value after an opaque function call.
443+
llvm::SmallPtrSet<const MemRegion *, 4> ExcludedRegions;
384444

385-
CallBack(CheckerContext &CC) : Ctx(CC), PoppedFrame(CC.getStackFrame()) {}
445+
CallBack(CheckerContext &CC, bool TopFrame)
446+
: Ctx(CC), PoppedFrame(CC.getStackFrame()), TopFrame(TopFrame) {}
386447

387448
bool HandleBinding(StoreManager &SMgr, Store S, const MemRegion *Region,
388449
SVal Val) override {
450+
recordInInvalidatedRegions(Region);
389451
const MemRegion *VR = Val.getAsRegion();
390452
if (!VR)
391453
return true;
@@ -394,15 +456,16 @@ void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS,
394456
return true;
395457

396458
// Check the globals for the same.
397-
if (!isa<GlobalsSpaceRegion>(Region->getMemorySpace()))
459+
if (!isa_and_nonnull<GlobalsSpaceRegion>(
460+
getStackOrGlobalSpaceRegion(Region)))
398461
return true;
399462
if (VR && VR->hasStackStorage() && !isNotInCurrentFrame(VR, Ctx))
400463
V.emplace_back(Region, VR);
401464
return true;
402465
}
403466
};
404467

405-
CallBack Cb(Ctx);
468+
CallBack Cb(Ctx, ExitingTopFrame);
406469
ProgramStateRef State = Node->getState();
407470
State->getStateManager().getStoreManager().iterBindings(State->getStore(),
408471
Cb);
@@ -423,6 +486,9 @@ void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS,
423486
for (const auto &P : Cb.V) {
424487
const MemRegion *Referrer = P.first->getBaseRegion();
425488
const MemRegion *Referred = P.second;
489+
if (Cb.ExcludedRegions.contains(getOriginBaseRegion(Referrer))) {
490+
continue;
491+
}
426492

427493
// Generate a report for this bug.
428494
const StringRef CommonSuffix =

clang/lib/StaticAnalyzer/Core/BugReporter.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2436,8 +2436,19 @@ PathSensitiveBugReport::getLocation() const {
24362436
if (auto FE = P.getAs<FunctionExitPoint>()) {
24372437
if (const ReturnStmt *RS = FE->getStmt())
24382438
return PathDiagnosticLocation::createBegin(RS, SM, LC);
2439+
2440+
// If we are exiting a destructor call, it is more useful to point to the
2441+
// next stmt which is usually the temporary declaration.
2442+
// For non-destructor and non-top-level calls, the next stmt will still
2443+
// refer to the last executed stmt of the body.
2444+
S = ErrorNode->getNextStmtForDiagnostics();
2445+
// If next stmt is not found, it is likely the end of a top-level function
2446+
// analysis. find the last execution statement then.
2447+
if (!S)
2448+
S = ErrorNode->getPreviousStmtForDiagnostics();
24392449
}
2440-
S = ErrorNode->getNextStmtForDiagnostics();
2450+
if (!S)
2451+
S = ErrorNode->getNextStmtForDiagnostics();
24412452
}
24422453

24432454
if (S) {

clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ const Stmt *ExplodedNode::getNextStmtForDiagnostics() const {
376376

377377
const Stmt *ExplodedNode::getPreviousStmtForDiagnostics() const {
378378
for (const ExplodedNode *N = getFirstPred(); N; N = N->getFirstPred())
379-
if (const Stmt *S = N->getStmtForDiagnostics())
379+
if (const Stmt *S = N->getStmtForDiagnostics(); S && !isa<CompoundStmt>(S))
380380
return S;
381381

382382
return nullptr;

clang/lib/StaticAnalyzer/Core/ExprEngine.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,8 +1072,6 @@ void ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out,
10721072
CleanedState, SFC, SymReaper);
10731073

10741074
// Process any special transfer function for dead symbols.
1075-
// A tag to track convenience transitions, which can be removed at cleanup.
1076-
static SimpleProgramPointTag cleanupTag(TagProviderName, "Clean Node");
10771075
// Call checkers with the non-cleaned state so that they could query the
10781076
// values of the soon to be dead symbols.
10791077
ExplodedNodeSet CheckedSet;
@@ -1102,10 +1100,15 @@ void ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out,
11021100
// generate a transition to that state.
11031101
ProgramStateRef CleanedCheckerSt =
11041102
StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
1105-
Bldr.generateNode(DiagnosticStmt, I, CleanedCheckerSt, &cleanupTag, K);
1103+
Bldr.generateNode(DiagnosticStmt, I, CleanedCheckerSt, cleanupNodeTag(), K);
11061104
}
11071105
}
11081106

1107+
const ProgramPointTag *ExprEngine::cleanupNodeTag() {
1108+
static SimpleProgramPointTag cleanupTag(TagProviderName, "Clean Node");
1109+
return &cleanupTag;
1110+
}
1111+
11091112
void ExprEngine::ProcessStmt(const Stmt *currStmt, ExplodedNode *Pred) {
11101113
// Reclaim any unnecessary nodes in the ExplodedGraph.
11111114
G.reclaimRecentlyAllocatedNodes();

clang/test/Analysis/copy-elision.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -158,19 +158,19 @@ ClassWithoutDestructor make1(AddressVector<ClassWithoutDestructor> &v) {
158158
return ClassWithoutDestructor(v);
159159
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
160160
object of type 'ClassWithoutDestructor' is still \
161-
referred to by the stack variable 'v' upon returning to the caller}}
161+
referred to by the caller variable 'v' upon returning to the caller}}
162162
}
163163
ClassWithoutDestructor make2(AddressVector<ClassWithoutDestructor> &v) {
164164
return make1(v);
165165
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
166166
object of type 'ClassWithoutDestructor' is still \
167-
referred to by the stack variable 'v' upon returning to the caller}}
167+
referred to by the caller variable 'v' upon returning to the caller}}
168168
}
169169
ClassWithoutDestructor make3(AddressVector<ClassWithoutDestructor> &v) {
170170
return make2(v);
171171
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
172172
object of type 'ClassWithoutDestructor' is still \
173-
referred to by the stack variable 'v' upon returning to the caller}}
173+
referred to by the caller variable 'v' upon returning to the caller}}
174174
}
175175

176176
void testMultipleReturns() {
@@ -193,7 +193,7 @@ void testMultipleReturns() {
193193
void consume(ClassWithoutDestructor c) {
194194
c.push();
195195
// expected-warning@-1 {{Address of stack memory associated with local \
196-
variable 'c' is still referred to by the stack variable 'v' upon returning \
196+
variable 'c' is still referred to by the caller variable 'v' upon returning \
197197
to the caller}}
198198
}
199199

@@ -267,7 +267,7 @@ struct TestCtorInitializer {
267267
: c(ClassWithDestructor(v)) {}
268268
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
269269
object of type 'ClassWithDestructor' is still referred \
270-
to by the stack variable 'v' upon returning to the caller}}
270+
to by the caller variable 'v' upon returning to the caller}}
271271
};
272272

273273
void testCtorInitializer() {
@@ -303,19 +303,19 @@ ClassWithDestructor make1(AddressVector<ClassWithDestructor> &v) {
303303
return ClassWithDestructor(v);
304304
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
305305
object of type 'ClassWithDestructor' is still referred \
306-
to by the stack variable 'v' upon returning to the caller}}
306+
to by the caller variable 'v' upon returning to the caller}}
307307
}
308308
ClassWithDestructor make2(AddressVector<ClassWithDestructor> &v) {
309309
return make1(v);
310310
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
311311
object of type 'ClassWithDestructor' is still referred \
312-
to by the stack variable 'v' upon returning to the caller}}
312+
to by the caller variable 'v' upon returning to the caller}}
313313
}
314314
ClassWithDestructor make3(AddressVector<ClassWithDestructor> &v) {
315315
return make2(v);
316316
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
317317
object of type 'ClassWithDestructor' is still referred \
318-
to by the stack variable 'v' upon returning to the caller}}
318+
to by the caller variable 'v' upon returning to the caller}}
319319
}
320320

321321
void testMultipleReturnsWithDestructors() {
@@ -360,7 +360,7 @@ void testMultipleReturnsWithDestructors() {
360360
void consume(ClassWithDestructor c) {
361361
c.push();
362362
// expected-warning@-1 {{Address of stack memory associated with local \
363-
variable 'c' is still referred to by the stack variable 'v' upon returning \
363+
variable 'c' is still referred to by the caller variable 'v' upon returning \
364364
to the caller}}
365365
}
366366

@@ -407,7 +407,7 @@ struct Foo {
407407
Foo make1(Foo **r) {
408408
return Foo(r);
409409
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
410-
object of type 'Foo' is still referred to by the stack \
410+
object of type 'Foo' is still referred to by the caller \
411411
variable 'z' upon returning to the caller}}
412412
}
413413

clang/test/Analysis/incorrect-checker-names.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ char const *p;
1616
void f0() {
1717
char const str[] = "This will change";
1818
p = str;
19-
} // expected-warning{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference [core.StackAddressEscape]}}
20-
// expected-note@-1{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}}
19+
} // expected-warning@-1{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference [core.StackAddressEscape]}}
20+
// expected-note@-2{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}}

clang/test/Analysis/loop-block-counts.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ void callee(void **p) {
66
int x;
77
*p = &x;
88
// expected-warning@-1 {{Address of stack memory associated with local \
9-
variable 'x' is still referred to by the stack variable 'arr' upon \
9+
variable 'x' is still referred to by the caller variable 'arr' upon \
1010
returning to the caller}}
1111
}
1212

0 commit comments

Comments
 (0)