Skip to content

Commit 2946108

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merge llvm/main into amd-debug
2 parents cc68e07 + 097f1e7 commit 2946108

File tree

79 files changed

+1746
-774
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

+1746
-774
lines changed

clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,17 @@ static unsigned getLength(const Expr *E,
6464
if (!E)
6565
return 0;
6666

67-
Expr::EvalResult Length;
6867
E = E->IgnoreImpCasts();
6968

7069
if (const auto *LengthDRE = dyn_cast<DeclRefExpr>(E))
7170
if (const auto *LengthVD = dyn_cast<VarDecl>(LengthDRE->getDecl()))
7271
if (!isa<ParmVarDecl>(LengthVD))
73-
if (const Expr *LengthInit = LengthVD->getInit())
72+
if (const Expr *LengthInit = LengthVD->getInit();
73+
LengthInit && !LengthInit->isValueDependent()) {
74+
Expr::EvalResult Length;
7475
if (LengthInit->EvaluateAsInt(Length, *Result.Context))
7576
return Length.Val.getInt().getZExtValue();
77+
}
7678

7779
if (const auto *LengthIL = dyn_cast<IntegerLiteral>(E))
7880
return LengthIL->getValue().getZExtValue();

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,10 @@ Changes in existing checks
274274
<clang-tidy/checks/bugprone/narrowing-conversions>` check by fixing
275275
false positive from analysis of a conditional expression in C.
276276

277+
- Improved :doc:`bugprone-not-null-terminated-result
278+
<clang-tidy/checks/bugprone/not-null-terminated-result>` check by fixing
279+
a crash caused by certain value-dependent expressions.
280+
277281
- Improved :doc:`bugprone-reserved-identifier
278282
<clang-tidy/checks/bugprone/reserved-identifier>` check by ignoring
279283
declarations and macros in system headers.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
2+
// RUN: -- -std=c++17 -I %S/Inputs/not-null-terminated-result
3+
4+
// This test case reproduces the crash when the check tries to evaluate
5+
// a value-dependent expression using EvaluateAsInt() in
6+
// bugprone-not-null-terminated-result, where the src parameter of memcpy is
7+
// value-dependent, but the length is not.
8+
9+
// expected-no-diagnostics
10+
11+
#include "not-null-terminated-result-cxx.h"
12+
13+
template<size_t N>
14+
class ValueDependentClass {
15+
public:
16+
void copyData(char* Dst) {
17+
const char* Src = reinterpret_cast<const char*>(this);
18+
// The length parameter is arbitrary, but the crash is not reproduced if it is N.
19+
memcpy(Dst, Src, 32);
20+
}
21+
};
22+
23+
template class ValueDependentClass<42>; // The template parameter value is arbitrary.

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ Bug Fixes in This Version
413413
(#GH159080)
414414
- Fixed a failed assertion with empty filename arguments in ``__has_embed``. (#GH159898)
415415
- Fixed a failed assertion with empty filename in ``#embed`` directive. (#GH162951)
416+
- Fixed a crash triggered by unterminated ``__has_embed``. (#GH162953)
416417

417418
Bug Fixes to Compiler Builtins
418419
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/ParentMapContext.cpp

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,6 @@
2020

2121
using namespace clang;
2222

23-
ParentMapContext::ParentMapContext(ASTContext &Ctx) : ASTCtx(Ctx) {}
24-
25-
ParentMapContext::~ParentMapContext() = default;
26-
27-
void ParentMapContext::clear() { Parents.reset(); }
28-
29-
const Expr *ParentMapContext::traverseIgnored(const Expr *E) const {
30-
return traverseIgnored(const_cast<Expr *>(E));
31-
}
32-
33-
Expr *ParentMapContext::traverseIgnored(Expr *E) const {
34-
if (!E)
35-
return nullptr;
36-
37-
switch (Traversal) {
38-
case TK_AsIs:
39-
return E;
40-
case TK_IgnoreUnlessSpelledInSource:
41-
return E->IgnoreUnlessSpelledInSource();
42-
}
43-
llvm_unreachable("Invalid Traversal type!");
44-
}
45-
46-
DynTypedNode ParentMapContext::traverseIgnored(const DynTypedNode &N) const {
47-
if (const auto *E = N.get<Expr>()) {
48-
return DynTypedNode::create(*traverseIgnored(E));
49-
}
50-
return N;
51-
}
52-
5323
template <typename T, typename... U>
5424
static std::tuple<bool, DynTypedNodeList, const T *, const U *...>
5525
matchParents(const DynTypedNodeList &NodeList,
@@ -334,6 +304,36 @@ matchParents(const DynTypedNodeList &NodeList,
334304
return MatchParents<T, U...>::match(NodeList, ParentMap);
335305
}
336306

307+
ParentMapContext::ParentMapContext(ASTContext &Ctx) : ASTCtx(Ctx) {}
308+
309+
ParentMapContext::~ParentMapContext() = default;
310+
311+
void ParentMapContext::clear() { Parents.reset(); }
312+
313+
const Expr *ParentMapContext::traverseIgnored(const Expr *E) const {
314+
return traverseIgnored(const_cast<Expr *>(E));
315+
}
316+
317+
Expr *ParentMapContext::traverseIgnored(Expr *E) const {
318+
if (!E)
319+
return nullptr;
320+
321+
switch (Traversal) {
322+
case TK_AsIs:
323+
return E;
324+
case TK_IgnoreUnlessSpelledInSource:
325+
return E->IgnoreUnlessSpelledInSource();
326+
}
327+
llvm_unreachable("Invalid Traversal type!");
328+
}
329+
330+
DynTypedNode ParentMapContext::traverseIgnored(const DynTypedNode &N) const {
331+
if (const auto *E = N.get<Expr>()) {
332+
return DynTypedNode::create(*traverseIgnored(E));
333+
}
334+
return N;
335+
}
336+
337337
/// Template specializations to abstract away from pointers and TypeLocs.
338338
/// @{
339339
template <typename T> static DynTypedNode createDynTypedNode(const T &Node) {

clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -939,8 +939,7 @@ const char *vTableClassNameForType(const CIRGenModule &cgm, const Type *ty) {
939939
case Type::Atomic:
940940
// FIXME: GCC treats block pointers as fundamental types?!
941941
case Type::BlockPointer:
942-
cgm.errorNYI("VTableClassNameForType: __fundamental_type_info");
943-
break;
942+
return "_ZTVN10__cxxabiv123__fundamental_type_infoE";
944943
case Type::ConstantArray:
945944
case Type::IncompleteArray:
946945
case Type::VariableArray:

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,12 +1793,20 @@ CIRToLLVMGlobalOpLowering::getComdatAttr(cir::GlobalOp &op,
17931793
if (!comdatOp) {
17941794
builder.setInsertionPointToStart(module.getBody());
17951795
comdatOp =
1796-
builder.create<mlir::LLVM::ComdatOp>(module.getLoc(), comdatName);
1796+
mlir::LLVM::ComdatOp::create(builder, module.getLoc(), comdatName);
1797+
}
1798+
1799+
if (auto comdatSelector = comdatOp.lookupSymbol<mlir::LLVM::ComdatSelectorOp>(
1800+
op.getSymName())) {
1801+
return mlir::SymbolRefAttr::get(
1802+
builder.getContext(), comdatName,
1803+
mlir::FlatSymbolRefAttr::get(comdatSelector.getSymNameAttr()));
17971804
}
17981805

17991806
builder.setInsertionPointToStart(&comdatOp.getBody().back());
1800-
auto selectorOp = builder.create<mlir::LLVM::ComdatSelectorOp>(
1801-
comdatOp.getLoc(), op.getSymName(), mlir::LLVM::comdat::Comdat::Any);
1807+
auto selectorOp = mlir::LLVM::ComdatSelectorOp::create(
1808+
builder, comdatOp.getLoc(), op.getSymName(),
1809+
mlir::LLVM::comdat::Comdat::Any);
18021810
return mlir::SymbolRefAttr::get(
18031811
builder.getContext(), comdatName,
18041812
mlir::FlatSymbolRefAttr::get(selectorOp.getSymNameAttr()));

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9248,8 +9248,9 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
92489248
options::OPT_nogpulibc)) {
92499249
forAllAssociatedToolChains(C, JA, getToolChain(), [&](const ToolChain &TC) {
92509250
// The device C library is only available for NVPTX and AMDGPU targets
9251-
// currently.
9252-
if (!TC.getTriple().isNVPTX() && !TC.getTriple().isAMDGPU())
9251+
// and we only link it by default for OpenMP currently.
9252+
if ((!TC.getTriple().isNVPTX() && !TC.getTriple().isAMDGPU()) ||
9253+
!JA.isHostOffloading(Action::OFK_OpenMP))
92539254
return;
92549255
bool HasLibC = TC.getStdlibIncludePath().has_value();
92559256
if (HasLibC) {

clang/lib/Format/WhitespaceManager.cpp

Lines changed: 26 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -289,17 +289,20 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
289289
SmallVector<WhitespaceManager::Change, 16> &Changes) {
290290
int Shift = 0;
291291

292-
// ScopeStack keeps track of the current scope depth. It contains indices of
293-
// the first token on each scope.
292+
// ScopeStack keeps track of the current scope depth. It contains the levels
293+
// of at most 2 scopes. The first one is the one that the matched token is
294+
// in. The second one is the one that should not be moved by this procedure.
294295
// The "Matches" indices should only have tokens from the outer-most scope.
295296
// However, we do need to pay special attention to one class of tokens
296-
// that are not in the outer-most scope, and that is function parameters
297-
// which are split across multiple lines, as illustrated by this example:
297+
// that are not in the outer-most scope, and that is the continuations of an
298+
// unwrapped line whose positions are derived from a token to the right of the
299+
// aligned token, as illustrated by this example:
298300
// double a(int x);
299301
// int b(int y,
300302
// double z);
301303
// In the above example, we need to take special care to ensure that
302-
// 'double z' is indented along with it's owning function 'b'.
304+
// 'double z' is indented along with its owning function 'b', because its
305+
// position is derived from the '(' token to the right of the 'b' token.
303306
// The same holds for calling a function:
304307
// double a = foo(x);
305308
// int b = bar(foo(y),
@@ -309,32 +312,28 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
309312
// auto s = "Hello"
310313
// "World";
311314
// Special handling is required for 'nested' ternary operators.
312-
SmallVector<unsigned, 16> ScopeStack;
315+
SmallVector<std::tuple<unsigned, unsigned, unsigned>, 2> ScopeStack;
313316

314317
for (unsigned i = Start; i != End; ++i) {
315318
auto &CurrentChange = Changes[i];
316319
if (!Matches.empty() && Matches[0] < i)
317320
Matches.consume_front();
318321
assert(Matches.empty() || Matches[0] >= i);
319-
if (!ScopeStack.empty() &&
320-
CurrentChange.indentAndNestingLevel() <
321-
Changes[ScopeStack.back()].indentAndNestingLevel()) {
322+
while (!ScopeStack.empty() &&
323+
CurrentChange.indentAndNestingLevel() < ScopeStack.back()) {
322324
ScopeStack.pop_back();
323325
}
324326

325-
// Compare current token to previous non-comment token to ensure whether
326-
// it is in a deeper scope or not.
327-
unsigned PreviousNonComment = i - 1;
328-
while (PreviousNonComment > Start &&
329-
Changes[PreviousNonComment].Tok->is(tok::comment)) {
330-
--PreviousNonComment;
331-
}
332-
if (i != Start && CurrentChange.indentAndNestingLevel() >
333-
Changes[PreviousNonComment].indentAndNestingLevel()) {
334-
ScopeStack.push_back(i);
327+
// Keep track of the level that should not move with the aligned token.
328+
if (ScopeStack.size() == 1u && CurrentChange.NewlinesBefore != 0u &&
329+
CurrentChange.indentAndNestingLevel() > ScopeStack[0] &&
330+
!CurrentChange.IsAligned) {
331+
ScopeStack.push_back(CurrentChange.indentAndNestingLevel());
335332
}
336333

337-
bool InsideNestedScope = !ScopeStack.empty();
334+
bool InsideNestedScope =
335+
!ScopeStack.empty() &&
336+
CurrentChange.indentAndNestingLevel() > ScopeStack[0];
338337
bool ContinuedStringLiteral = i > Start &&
339338
CurrentChange.Tok->is(tok::string_literal) &&
340339
Changes[i - 1].Tok->is(tok::string_literal);
@@ -349,103 +348,20 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
349348
if (!Matches.empty() && Matches[0] == i) {
350349
Shift = Column - (RightJustify ? CurrentChange.TokenLength : 0) -
351350
CurrentChange.StartOfTokenColumn;
351+
ScopeStack = {CurrentChange.indentAndNestingLevel()};
352352
CurrentChange.Spaces += Shift;
353353
}
354354

355355
if (Shift == 0)
356356
continue;
357357

358-
// This is for function parameters that are split across multiple lines,
359-
// as mentioned in the ScopeStack comment.
360-
if (InsideNestedScope && CurrentChange.NewlinesBefore > 0) {
361-
unsigned ScopeStart = ScopeStack.back();
362-
auto ShouldShiftBeAdded = [&] {
363-
// Function declaration
364-
if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName))
365-
return true;
366-
367-
// Lambda.
368-
if (Changes[ScopeStart - 1].Tok->is(TT_LambdaLBrace))
369-
return false;
370-
371-
// Continued function declaration
372-
if (ScopeStart > Start + 1 &&
373-
Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)) {
374-
return true;
375-
}
376-
377-
// Continued (template) function call.
378-
if (ScopeStart > Start + 1 &&
379-
Changes[ScopeStart - 2].Tok->isOneOf(tok::identifier,
380-
TT_TemplateCloser) &&
381-
Changes[ScopeStart - 1].Tok->is(tok::l_paren) &&
382-
Changes[ScopeStart].Tok->isNot(TT_LambdaLSquare)) {
383-
if (CurrentChange.Tok->MatchingParen &&
384-
CurrentChange.Tok->MatchingParen->is(TT_LambdaLBrace)) {
385-
return false;
386-
}
387-
if (Changes[ScopeStart].NewlinesBefore > 0)
388-
return false;
389-
if (CurrentChange.Tok->is(tok::l_brace) &&
390-
CurrentChange.Tok->is(BK_BracedInit)) {
391-
return true;
392-
}
393-
return Style.BinPackArguments;
394-
}
395-
396-
// Ternary operator
397-
if (CurrentChange.Tok->is(TT_ConditionalExpr))
398-
return true;
399-
400-
// Period Initializer .XXX = 1.
401-
if (CurrentChange.Tok->is(TT_DesignatedInitializerPeriod))
402-
return true;
403-
404-
// Continued ternary operator
405-
if (CurrentChange.Tok->Previous &&
406-
CurrentChange.Tok->Previous->is(TT_ConditionalExpr)) {
407-
return true;
408-
}
409-
410-
// Continued direct-list-initialization using braced list.
411-
if (ScopeStart > Start + 1 &&
412-
Changes[ScopeStart - 2].Tok->is(tok::identifier) &&
413-
Changes[ScopeStart - 1].Tok->is(tok::l_brace) &&
414-
CurrentChange.Tok->is(tok::l_brace) &&
415-
CurrentChange.Tok->is(BK_BracedInit)) {
416-
return true;
417-
}
418-
419-
// Continued braced list.
420-
if (ScopeStart > Start + 1 &&
421-
Changes[ScopeStart - 2].Tok->isNot(tok::identifier) &&
422-
Changes[ScopeStart - 1].Tok->is(tok::l_brace) &&
423-
CurrentChange.Tok->isNot(tok::r_brace)) {
424-
for (unsigned OuterScopeStart : llvm::reverse(ScopeStack)) {
425-
// Lambda.
426-
if (OuterScopeStart > Start &&
427-
Changes[OuterScopeStart - 1].Tok->is(TT_LambdaLBrace)) {
428-
return false;
429-
}
430-
}
431-
if (Changes[ScopeStart].NewlinesBefore > 0)
432-
return false;
433-
return true;
434-
}
435-
436-
// Continued template parameter.
437-
if (Changes[ScopeStart - 1].Tok->is(TT_TemplateOpener))
438-
return true;
439-
440-
return false;
441-
};
442-
443-
if (ShouldShiftBeAdded())
444-
CurrentChange.Spaces += Shift;
445-
}
446-
447-
if (ContinuedStringLiteral)
358+
// This is for lines that are split across multiple lines, as mentioned in
359+
// the ScopeStack comment. The stack size being 1 means that the token is
360+
// not in a scope that should not move.
361+
if (ScopeStack.size() == 1u && CurrentChange.NewlinesBefore > 0 &&
362+
(ContinuedStringLiteral || InsideNestedScope)) {
448363
CurrentChange.Spaces += Shift;
364+
}
449365

450366
// We should not remove required spaces unless we break the line before.
451367
assert(Shift > 0 || Changes[i].NewlinesBefore > 0 ||

clang/lib/Lex/PPDirectives.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3665,14 +3665,14 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) {
36653665
std::pair<tok::TokenKind, SourceLocation> Matches) {
36663666
Diag(CurTok, diag::err_expected) << Expected;
36673667
Diag(Matches.second, diag::note_matching) << Matches.first;
3668-
if (CurTok.isNot(tok::eod))
3668+
if (CurTok.isNot(EndTokenKind))
36693669
DiscardUntilEndOfDirective(CurTok);
36703670
};
36713671

36723672
auto ExpectOrDiagAndSkipToEOD = [&](tok::TokenKind Kind) {
36733673
if (CurTok.isNot(Kind)) {
36743674
Diag(CurTok, diag::err_expected) << Kind;
3675-
if (CurTok.isNot(tok::eod))
3675+
if (CurTok.isNot(EndTokenKind))
36763676
DiscardUntilEndOfDirective(CurTok);
36773677
return false;
36783678
}
@@ -3763,7 +3763,7 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) {
37633763
if (Result.isNegative()) {
37643764
Diag(CurTok, diag::err_requires_positive_value)
37653765
<< toString(Result, 10) << /*positive*/ 0;
3766-
if (CurTok.isNot(tok::eod))
3766+
if (CurTok.isNot(EndTokenKind))
37673767
DiscardUntilEndOfDirective(CurTok);
37683768
return std::nullopt;
37693769
}
@@ -3906,7 +3906,7 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) {
39063906
}
39073907
if (!ForHasEmbed) {
39083908
Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 << Parameter;
3909-
if (CurTok.isNot(tok::eod))
3909+
if (CurTok.isNot(EndTokenKind))
39103910
DiscardUntilEndOfDirective(CurTok);
39113911
return std::nullopt;
39123912
}

0 commit comments

Comments
 (0)