Skip to content

Commit 1373bde

Browse files
committed
Merge remote-tracking branch 'upstream/release/18.x' into ldc-release/18.x
2 parents 9013f36 + 617a15a commit 1373bde

File tree

64 files changed

+1713
-227
lines changed

Some content is hidden

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

64 files changed

+1713
-227
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ ABI Changes in This Version
149149
- Following the SystemV ABI for x86-64, ``__int128`` arguments will no longer
150150
be split between a register and a stack slot.
151151

152+
- Fixed Microsoft calling convention for returning certain classes with a
153+
templated constructor. If a class has a templated constructor, it should
154+
be returned indirectly even if it meets all the other requirements for
155+
returning a class in a register. This affects some uses of std::pair.
156+
(#GH86384).
157+
152158
AST Dumping Potentially Breaking Changes
153159
----------------------------------------
154160
- When dumping a sugared type, Clang will no longer print the desugared type if
@@ -1474,6 +1480,10 @@ Crash and bug fixes
14741480
- Fix false positive in mutation check when using pointer to member function.
14751481
(`#66204 <https://github.com/llvm/llvm-project/issues/66204>`_)
14761482

1483+
- Fixed a crash in ``security.cert.env.InvalidPtr`` checker when accidentally
1484+
matched user-defined ``strerror`` and similar library functions.
1485+
(`#88181 <https://github.com/llvm/llvm-project/issues/88181>`_)
1486+
14771487
Improvements
14781488
^^^^^^^^^^^^
14791489

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -823,29 +823,32 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField(
823823
ASTContext &Ctx, const RecordDecl *RD, StringRef Name, uint64_t &Offset) {
824824
const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
825825
getLangOpts().getStrictFlexArraysLevel();
826-
unsigned FieldNo = 0;
827-
bool IsUnion = RD->isUnion();
826+
uint32_t FieldNo = 0;
828827

829-
for (const Decl *D : RD->decls()) {
830-
if (const auto *Field = dyn_cast<FieldDecl>(D);
831-
Field && (Name.empty() || Field->getNameAsString() == Name) &&
828+
if (RD->isImplicit())
829+
return nullptr;
830+
831+
for (const FieldDecl *FD : RD->fields()) {
832+
if ((Name.empty() || FD->getNameAsString() == Name) &&
832833
Decl::isFlexibleArrayMemberLike(
833-
Ctx, Field, Field->getType(), StrictFlexArraysLevel,
834+
Ctx, FD, FD->getType(), StrictFlexArraysLevel,
834835
/*IgnoreTemplateOrMacroSubstitution=*/true)) {
835836
const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
836837
Offset += Layout.getFieldOffset(FieldNo);
837-
return Field;
838+
return FD;
838839
}
839840

840-
if (const auto *Record = dyn_cast<RecordDecl>(D))
841-
if (const FieldDecl *Field =
842-
FindFlexibleArrayMemberField(Ctx, Record, Name, Offset)) {
841+
QualType Ty = FD->getType();
842+
if (Ty->isRecordType()) {
843+
if (const FieldDecl *Field = FindFlexibleArrayMemberField(
844+
Ctx, Ty->getAsRecordDecl(), Name, Offset)) {
843845
const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
844846
Offset += Layout.getFieldOffset(FieldNo);
845847
return Field;
846848
}
849+
}
847850

848-
if (!IsUnion && isa<FieldDecl>(D))
851+
if (!RD->isUnion())
849852
++FieldNo;
850853
}
851854

clang/lib/CodeGen/CGCall.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,6 +1581,11 @@ bool CodeGenModule::ReturnTypeUsesSRet(const CGFunctionInfo &FI) {
15811581
return RI.isIndirect() || (RI.isInAlloca() && RI.getInAllocaSRet());
15821582
}
15831583

1584+
bool CodeGenModule::ReturnTypeHasInReg(const CGFunctionInfo &FI) {
1585+
const auto &RI = FI.getReturnInfo();
1586+
return RI.getInReg();
1587+
}
1588+
15841589
bool CodeGenModule::ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI) {
15851590
return ReturnTypeUsesSRet(FI) &&
15861591
getTargetCodeGenInfo().doesReturnSlotInterfereWithArgs();

clang/lib/CodeGen/CGObjCGNU.cpp

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2903,23 +2903,29 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF,
29032903
break;
29042904
case CodeGenOptions::Mixed:
29052905
case CodeGenOptions::NonLegacy:
2906+
StringRef name = "objc_msgSend";
29062907
if (CGM.ReturnTypeUsesFPRet(ResultType)) {
2907-
imp =
2908-
CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
2909-
"objc_msgSend_fpret")
2910-
.getCallee();
2908+
name = "objc_msgSend_fpret";
29112909
} else if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
2912-
// The actual types here don't matter - we're going to bitcast the
2913-
// function anyway
2914-
imp =
2915-
CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
2916-
"objc_msgSend_stret")
2917-
.getCallee();
2918-
} else {
2919-
imp = CGM.CreateRuntimeFunction(
2920-
llvm::FunctionType::get(IdTy, IdTy, true), "objc_msgSend")
2921-
.getCallee();
2910+
name = "objc_msgSend_stret";
2911+
2912+
// The address of the memory block is be passed in x8 for POD type,
2913+
// or in x0 for non-POD type (marked as inreg).
2914+
bool shouldCheckForInReg =
2915+
CGM.getContext()
2916+
.getTargetInfo()
2917+
.getTriple()
2918+
.isWindowsMSVCEnvironment() &&
2919+
CGM.getContext().getTargetInfo().getTriple().isAArch64();
2920+
if (shouldCheckForInReg && CGM.ReturnTypeHasInReg(MSI.CallInfo)) {
2921+
name = "objc_msgSend_stret2";
2922+
}
29222923
}
2924+
// The actual types here don't matter - we're going to bitcast the
2925+
// function anyway
2926+
imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
2927+
name)
2928+
.getCallee();
29232929
}
29242930

29252931
// Reset the receiver in case the lookup modified it

clang/lib/CodeGen/CodeGenModule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,9 @@ class CodeGenModule : public CodeGenTypeCache {
12391239
/// Return true iff the given type uses 'sret' when used as a return type.
12401240
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI);
12411241

1242+
/// Return true iff the given type has `inreg` set.
1243+
bool ReturnTypeHasInReg(const CGFunctionInfo &FI);
1244+
12421245
/// Return true iff the given type uses an argument slot when 'sret' is used
12431246
/// as a return type.
12441247
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI);

clang/lib/CodeGen/CoverageMappingGen.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,12 @@ struct CounterCoverageMappingBuilder
12071207
/// Find a valid gap range between \p AfterLoc and \p BeforeLoc.
12081208
std::optional<SourceRange> findGapAreaBetween(SourceLocation AfterLoc,
12091209
SourceLocation BeforeLoc) {
1210+
// Some statements (like AttributedStmt and ImplicitValueInitExpr) don't
1211+
// have valid source locations. Do not emit a gap region if this is the case
1212+
// in either AfterLoc end or BeforeLoc end.
1213+
if (AfterLoc.isInvalid() || BeforeLoc.isInvalid())
1214+
return std::nullopt;
1215+
12101216
// If AfterLoc is in function-like macro, use the right parenthesis
12111217
// location.
12121218
if (AfterLoc.isMacroID()) {
@@ -1370,9 +1376,8 @@ struct CounterCoverageMappingBuilder
13701376
for (const Stmt *Child : S->children())
13711377
if (Child) {
13721378
// If last statement contains terminate statements, add a gap area
1373-
// between the two statements. Skipping attributed statements, because
1374-
// they don't have valid start location.
1375-
if (LastStmt && HasTerminateStmt && !isa<AttributedStmt>(Child)) {
1379+
// between the two statements.
1380+
if (LastStmt && HasTerminateStmt) {
13761381
auto Gap = findGapAreaBetween(getEnd(LastStmt), getStart(Child));
13771382
if (Gap)
13781383
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(),

clang/lib/CodeGen/MicrosoftCXXABI.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,9 +1135,15 @@ static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty,
11351135
return false;
11361136
if (RD->hasNonTrivialCopyAssignment())
11371137
return false;
1138-
for (const CXXConstructorDecl *Ctor : RD->ctors())
1139-
if (Ctor->isUserProvided())
1140-
return false;
1138+
for (const Decl *D : RD->decls()) {
1139+
if (auto *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
1140+
if (Ctor->isUserProvided())
1141+
return false;
1142+
} else if (auto *Template = dyn_cast<FunctionTemplateDecl>(D)) {
1143+
if (isa<CXXConstructorDecl>(Template->getTemplatedDecl()))
1144+
return false;
1145+
}
1146+
}
11411147
if (RD->hasNonTrivialDestructor())
11421148
return false;
11431149
return true;

clang/lib/Format/ContinuationIndenter.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,13 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
674674
// arguments to function calls. We do this by ensuring that either all
675675
// arguments (including any lambdas) go on the same line as the function
676676
// call, or we break before the first argument.
677-
auto PrevNonComment = Current.getPreviousNonComment();
677+
const auto *Prev = Current.Previous;
678+
if (!Prev)
679+
return false;
680+
// For example, `/*Newline=*/false`.
681+
if (Prev->is(TT_BlockComment) && Current.SpacesRequiredBefore == 0)
682+
return false;
683+
const auto *PrevNonComment = Current.getPreviousNonComment();
678684
if (!PrevNonComment || PrevNonComment->isNot(tok::l_paren))
679685
return false;
680686
if (Current.isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3532,6 +3532,8 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
35323532
}
35333533
} else if (ClosingParen) {
35343534
for (auto *Tok = ClosingParen->Next; Tok; Tok = Tok->Next) {
3535+
if (Tok->is(TT_CtorInitializerColon))
3536+
break;
35353537
if (Tok->is(tok::arrow)) {
35363538
Tok->setType(TT_TrailingReturnArrow);
35373539
break;
@@ -5157,12 +5159,8 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
51575159
return true;
51585160
if (Left.IsUnterminatedLiteral)
51595161
return true;
5160-
// FIXME: Breaking after newlines seems useful in general. Turn this into an
5161-
// option and recognize more cases like endl etc, and break independent of
5162-
// what comes after operator lessless.
5163-
if (Right.is(tok::lessless) && Right.Next &&
5164-
Right.Next->is(tok::string_literal) && Left.is(tok::string_literal) &&
5165-
Left.TokenText.ends_with("\\n\"")) {
5162+
if (Right.is(tok::lessless) && Right.Next && Left.is(tok::string_literal) &&
5163+
Right.Next->is(tok::string_literal)) {
51665164
return true;
51675165
}
51685166
if (Right.is(TT_RequiresClause)) {

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -489,18 +489,23 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
489489
};
490490
SmallVector<StackEntry, 8> LBraceStack;
491491
assert(Tok->is(tok::l_brace));
492+
492493
do {
493-
// Get next non-comment, non-preprocessor token.
494494
FormatToken *NextTok;
495495
do {
496496
NextTok = Tokens->getNextToken();
497497
} while (NextTok->is(tok::comment));
498-
while (NextTok->is(tok::hash) && !Line->InMacroBody) {
499-
NextTok = Tokens->getNextToken();
500-
do {
501-
NextTok = Tokens->getNextToken();
502-
} while (NextTok->is(tok::comment) ||
503-
(NextTok->NewlinesBefore == 0 && NextTok->isNot(tok::eof)));
498+
499+
if (!Line->InMacroBody) {
500+
// Skip PPDirective lines and comments.
501+
while (NextTok->is(tok::hash)) {
502+
do {
503+
NextTok = Tokens->getNextToken();
504+
} while (NextTok->NewlinesBefore == 0 && NextTok->isNot(tok::eof));
505+
506+
while (NextTok->is(tok::comment))
507+
NextTok = Tokens->getNextToken();
508+
}
504509
}
505510

506511
switch (Tok->Tok.getKind()) {
@@ -534,16 +539,6 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
534539
if (Style.Language == FormatStyle::LK_Proto) {
535540
ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
536541
} else {
537-
// Skip NextTok over preprocessor lines, otherwise we may not
538-
// properly diagnose the block as a braced intializer
539-
// if the comma separator appears after the pp directive.
540-
while (NextTok->is(tok::hash)) {
541-
ScopedMacroState MacroState(*Line, Tokens, NextTok);
542-
do {
543-
NextTok = Tokens->getNextToken();
544-
} while (NextTok->isNot(tok::eof));
545-
}
546-
547542
// Using OriginalColumn to distinguish between ObjC methods and
548543
// binary operators is a bit hacky.
549544
bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
@@ -602,6 +597,16 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
602597
NextTok = Tokens->getNextToken();
603598
ProbablyBracedList = NextTok->isNot(tok::l_square);
604599
}
600+
601+
// Cpp macro definition body that is a nonempty braced list or block:
602+
if (Style.isCpp() && Line->InMacroBody && PrevTok != FormatTok &&
603+
!FormatTok->Previous && NextTok->is(tok::eof) &&
604+
// A statement can end with only `;` (simple statement), a block
605+
// closing brace (compound statement), or `:` (label statement).
606+
// If PrevTok is a block opening brace, Tok ends an empty block.
607+
!PrevTok->isOneOf(tok::semi, BK_Block, tok::colon)) {
608+
ProbablyBracedList = true;
609+
}
605610
}
606611
if (ProbablyBracedList) {
607612
Tok->setBlockKind(BK_BracedInit);
@@ -631,6 +636,7 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
631636
default:
632637
break;
633638
}
639+
634640
PrevTok = Tok;
635641
Tok = NextTok;
636642
} while (Tok->isNot(tok::eof) && !LBraceStack.empty());

clang/lib/StaticAnalyzer/Checkers/Taint.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -216,21 +216,17 @@ std::vector<SymbolRef> taint::getTaintedSymbolsImpl(ProgramStateRef State,
216216
std::vector<SymbolRef> TaintedSymbols;
217217
if (!Reg)
218218
return TaintedSymbols;
219-
// Element region (array element) is tainted if either the base or the offset
220-
// are tainted.
219+
220+
// Element region (array element) is tainted if the offset is tainted.
221221
if (const ElementRegion *ER = dyn_cast<ElementRegion>(Reg)) {
222222
std::vector<SymbolRef> TaintedIndex =
223223
getTaintedSymbolsImpl(State, ER->getIndex(), K, returnFirstOnly);
224224
llvm::append_range(TaintedSymbols, TaintedIndex);
225225
if (returnFirstOnly && !TaintedSymbols.empty())
226226
return TaintedSymbols; // return early if needed
227-
std::vector<SymbolRef> TaintedSuperRegion =
228-
getTaintedSymbolsImpl(State, ER->getSuperRegion(), K, returnFirstOnly);
229-
llvm::append_range(TaintedSymbols, TaintedSuperRegion);
230-
if (returnFirstOnly && !TaintedSymbols.empty())
231-
return TaintedSymbols; // return early if needed
232227
}
233228

229+
// Symbolic region is tainted if the corresponding symbol is tainted.
234230
if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg)) {
235231
std::vector<SymbolRef> TaintedRegions =
236232
getTaintedSymbolsImpl(State, SR->getSymbol(), K, returnFirstOnly);
@@ -239,6 +235,8 @@ std::vector<SymbolRef> taint::getTaintedSymbolsImpl(ProgramStateRef State,
239235
return TaintedSymbols; // return early if needed
240236
}
241237

238+
// Any subregion (including Element and Symbolic regions) is tainted if its
239+
// super-region is tainted.
242240
if (const SubRegion *ER = dyn_cast<SubRegion>(Reg)) {
243241
std::vector<SymbolRef> TaintedSubRegions =
244242
getTaintedSymbolsImpl(State, ER->getSuperRegion(), K, returnFirstOnly);
@@ -318,4 +316,4 @@ std::vector<SymbolRef> taint::getTaintedSymbolsImpl(ProgramStateRef State,
318316
}
319317
}
320318
return TaintedSymbols;
321-
}
319+
}

clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,12 @@ void InvalidPtrChecker::postPreviousReturnInvalidatingCall(
205205
CE, LCtx, CE->getType(), C.blockCount());
206206
State = State->BindExpr(CE, LCtx, RetVal);
207207

208+
const auto *SymRegOfRetVal =
209+
dyn_cast_or_null<SymbolicRegion>(RetVal.getAsRegion());
210+
if (!SymRegOfRetVal)
211+
return;
212+
208213
// Remember to this region.
209-
const auto *SymRegOfRetVal = cast<SymbolicRegion>(RetVal.getAsRegion());
210214
const MemRegion *MR = SymRegOfRetVal->getBaseRegion();
211215
State = State->set<PreviousCallResultMap>(FD, MR);
212216

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=core,security.cert.env.InvalidPtr -verify %s
2+
3+
// expected-no-diagnostics
4+
5+
namespace other {
6+
int strerror(int errnum); // custom strerror
7+
void no_crash_on_custom_strerror() {
8+
(void)strerror(0); // no-crash
9+
}
10+
} // namespace other

clang/test/CodeGen/arm64-microsoft-arguments.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,18 @@ S11 f11() {
201201
S11 x;
202202
return func11(x);
203203
}
204+
205+
// GH86384
206+
// Pass and return object with template constructor (pass directly,
207+
// return indirectly).
208+
// CHECK: define dso_local void @"?f12@@YA?AUS12@@XZ"(ptr dead_on_unwind inreg noalias writable sret(%struct.S12) align 4 {{.*}})
209+
// CHECK: call void @"?func12@@YA?AUS12@@U1@@Z"(ptr dead_on_unwind inreg writable sret(%struct.S12) align 4 {{.*}}, i64 {{.*}})
210+
struct S12 {
211+
template<typename T> S12(T*) {}
212+
int x;
213+
};
214+
S12 func12(S12 x);
215+
S12 f12() {
216+
S12 x((int*)0);
217+
return func12(x);
218+
}

0 commit comments

Comments
 (0)