Skip to content

Commit 2a38c3f

Browse files
committed
Merge branch 'main' into complete-copyable-types
2 parents 642026b + 8effc6c commit 2a38c3f

34 files changed

Lines changed: 718 additions & 35 deletions

cfg/windows.cfg

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,11 @@
13311331
<alloc init="true" arg="11">AllocateAndInitializeSid</alloc>
13321332
<dealloc>FreeSid</dealloc>
13331333
</memory>
1334+
<memory>
1335+
<alloc init="true">_create_locale</alloc>
1336+
<alloc init="true">_wcreate_locale</alloc>
1337+
<dealloc>_free_locale</dealloc>
1338+
</memory>
13341339
<!--SIZE_T RtlCompareMemory(
13351340
_In_ const VOID *Source1,
13361341
_In_ const VOID *Source2,
@@ -5591,6 +5596,38 @@ HFONT CreateFont(
55915596
<not-uninit/>
55925597
</arg>
55935598
</function>
5599+
<!--_locale_t _create_locale(int category, const char *locale);
5600+
_locale_t _wcreate_locale(int category, const wchar_t *locale);
5601+
void _free_locale(_locale_t locale);-->
5602+
<function name="_create_locale">
5603+
<returnValue type="_locale_t"/>
5604+
<noreturn>false</noreturn>
5605+
<use-retval/>
5606+
<arg nr="1" direction="in">
5607+
<not-uninit/>
5608+
</arg>
5609+
<arg nr="2" direction="in">
5610+
<not-uninit/>
5611+
</arg>
5612+
</function>
5613+
<function name="_wcreate_locale">
5614+
<returnValue type="_locale_t"/>
5615+
<noreturn>false</noreturn>
5616+
<use-retval/>
5617+
<arg nr="1" direction="in">
5618+
<not-uninit/>
5619+
</arg>
5620+
<arg nr="2" direction="in">
5621+
<not-uninit/>
5622+
</arg>
5623+
</function>
5624+
<function name="_free_locale">
5625+
<noreturn>false</noreturn>
5626+
<returnValue type="void"/>
5627+
<arg nr="1">
5628+
<not-uninit/>
5629+
</arg>
5630+
</function>
55945631
<!--char * strlwr(_Inout_z_ char * _Str);-->
55955632
<function name="strlwr">
55965633
<returnValue type="char *">arg1</returnValue>

gui/resultsview.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ void ResultsView::logCopyComplete()
518518
const QListWidgetItem * item = mUI->mListLog->item(i);
519519
if (nullptr != item) {
520520
logText += item->text();
521+
logText += "\n";
521522
}
522523
}
523524
QClipboard *clipboard = QApplication::clipboard();

lib/astutils.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,7 +1701,7 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Se
17011701
compare = true;
17021702
}
17031703
}
1704-
if (compare && astIsBoolLike(varTok1, settings) && astIsBoolLike(varTok2, settings))
1704+
if (compare && varTok1 != varTok2 && astIsBoolLike(varTok1, settings) && astIsBoolLike(varTok2, settings))
17051705
return isSameExpression(macro, varTok1, varTok2, settings, pure, followVar, errors);
17061706

17071707
}
@@ -2779,7 +2779,7 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings &settings,
27792779
if (ftok->str() == "(" && Token::simpleMatch(ftok->astOperand1(), "[")) // operator() on array element, bail out
27802780
return true;
27812781
const Token * ptok = tok2;
2782-
while (Token::Match(ptok->astParent(), ".|::|["))
2782+
while (Token::Match(ptok->astParent(), ".|::"))
27832783
ptok = ptok->astParent();
27842784
int pindirect = indirect;
27852785
if (indirect == 0 && astIsLHS(tok2) && Token::Match(ptok, ". %var%") && astIsPointer(ptok->next()))
@@ -3002,7 +3002,7 @@ bool isVariableChanged(const Variable * var, const Settings &settings, int depth
30023002
const Token * start = var->declEndToken();
30033003
if (!start)
30043004
return false;
3005-
if (Token::Match(start, "; %varid% =", var->declarationId()) && !Token::simpleMatch(start->previous(), ")"))
3005+
if (start->isSplittedVarDeclEq() && Token::Match(start, "; %varid% =", var->declarationId()))
30063006
start = start->tokAt(2);
30073007
if (Token::simpleMatch(start, "=")) {
30083008
const Token* next = nextAfterAstRightmostLeafGeneric(start);
@@ -3919,3 +3919,23 @@ const Token *skipUnreachableBranch(const Token *tok)
39193919

39203920
return tok;
39213921
}
3922+
3923+
bool isEscapeKeyword(const Token *tok, const Settings &settings)
3924+
{
3925+
if (!tok)
3926+
return false;
3927+
3928+
if (tok->str() == "return")
3929+
return true;
3930+
3931+
if (!tok->isCpp())
3932+
return false;
3933+
3934+
if (tok->str() == "throw")
3935+
return true;
3936+
3937+
if (settings.standards.cpp < Standards::CPP20)
3938+
return false;
3939+
3940+
return tok->str() == "co_return";
3941+
}

lib/astutils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,4 +463,6 @@ bool isUnreachableOperand(const Token *tok);
463463

464464
const Token *skipUnreachableBranch(const Token *tok);
465465

466+
bool isEscapeKeyword(const Token *tok, const Settings &settings);
467+
466468
#endif // astutilsH

lib/checkassert.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ void CheckAssertImpl::assertWithSideEffects()
8383
if (!scope) {
8484
// guess that const method doesn't have side effects
8585
if (f->nestedIn->isClassOrStruct() && !f->isConst() && !f->isStatic())
86-
sideEffectInAssertError(tmp, f->name()); // Non-const member function called, assume it has side effects
86+
sideEffectInAssertError(tmp, f->name(), " If there are no side effects, consider declaring the method const."); // Non-const member function called, assume it has side effects
8787
continue;
8888
}
8989

@@ -117,12 +117,12 @@ void CheckAssertImpl::assertWithSideEffects()
117117
//---------------------------------------------------------------------------
118118

119119

120-
void CheckAssertImpl::sideEffectInAssertError(const Token *tok, const std::string& functionName)
120+
void CheckAssertImpl::sideEffectInAssertError(const Token *tok, const std::string& functionName, const std::string &extra)
121121
{
122122
reportError(tok, Severity::warning,
123123
"assertWithSideEffect",
124124
"$symbol:" + functionName + "\n"
125-
"Assert statement calls a function which may have desired side effects: '$symbol'.\n"
125+
"Assert statement calls a function which may have desired side effects: '$symbol'." + extra + "\n"
126126
"Non-pure function: '$symbol' is called inside assert statement. "
127127
"Assert statements are removed from release builds so the code inside "
128128
"assert statement is not executed. If the code is needed also in release "

lib/checkassert.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class CPPCHECKLIB CheckAssertImpl : public CheckImpl {
6565
void checkVariableAssignment(const Token* assignTok, const Scope *assertionScope);
6666
static bool inSameScope(const Token* returnTok, const Token* assignTok);
6767

68-
void sideEffectInAssertError(const Token *tok, const std::string& functionName);
68+
void sideEffectInAssertError(const Token *tok, const std::string& functionName, const std::string &extra = "");
6969
void assignmentInAssertError(const Token *tok, const std::string &varname);
7070
};
7171
/// @}

lib/checkbufferoverrun.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -560,12 +560,18 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons
560560
if (!bufTok->valueType())
561561
return ValueFlow::Value(-1);
562562

563+
MathLib::bigint index = 0;
563564
if (bufTok->isUnaryOp("&")) {
564565
bufTok = bufTok->astOperand1();
565566
if (Token::simpleMatch(bufTok, "[")) {
566-
const Token* index = bufTok->astOperand2();
567-
if (!(index && index->hasKnownIntValue() && index->getKnownIntValue() == 0))
568-
return ValueFlow::Value(-1);
567+
if (const Token* indexTok = bufTok->astOperand2()) {
568+
if (indexTok->hasKnownIntValue())
569+
index = indexTok->getKnownIntValue();
570+
else if (const ValueFlow::Value* maxValue = indexTok->getMaxValue(false))
571+
index = maxValue->intvalue;
572+
else
573+
return ValueFlow::Value(-1);
574+
}
569575
bufTok = bufTok->astOperand1();
570576
}
571577
}
@@ -575,7 +581,7 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons
575581
if (const ValueFlow::Value *value = getBufferSizeValue(bufTok)) {
576582
if (value->isBufferSizeValue())
577583
return *value;
578-
if (value->isContainerSizeValue() && bufTok->valueType() && bufTok->valueType()->container) {
584+
if (value->isContainerSizeValue() && bufTok->valueType() && bufTok->valueType()->containerTypeToken) {
579585
const ValueType vtElement = ValueType::parseDecl(bufTok->valueType()->containerTypeToken, settings);
580586
const size_t elementSize = vtElement.getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer);
581587
if (elementSize > 0) {
@@ -600,10 +606,10 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons
600606
v.valueType = ValueFlow::Value::ValueType::BUFFER_SIZE;
601607

602608
if (var->isPointerArray())
603-
v.intvalue = dim * mSettings.platform.sizeof_pointer;
609+
v.intvalue = (dim - index) * mSettings.platform.sizeof_pointer;
604610
else {
605611
const size_t typeSize = bufTok->valueType()->getSizeOf(mSettings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointee);
606-
v.intvalue = dim * typeSize;
612+
v.intvalue = (dim - index) * typeSize;
607613
}
608614

609615
return v;

lib/checkfunctions.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,8 @@ void CheckFunctionsImpl::checkMissingReturn()
329329
continue;
330330
if (Function::returnsVoid(function, true))
331331
continue;
332+
if (Function::isCoroutine(function, mSettings.standards, *mTokenizer))
333+
continue;
332334
const Token *errorToken = checkMissingReturnScope(scope->bodyEnd, mSettings.library);
333335
if (errorToken)
334336
missingReturnError(errorToken);

lib/checkother.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -701,8 +701,12 @@ void CheckOtherImpl::checkRedundantAssignment()
701701
// Get next assignment..
702702
const Token *nextAssign = fwdAnalysis.reassign(tokenToCheck, start, scope->bodyEnd);
703703
// extra check for union
704-
if (nextAssign && tokenToCheck != tok->astOperand1())
704+
if (nextAssign && tokenToCheck != tok->astOperand1()) {
705705
nextAssign = fwdAnalysis.reassign(tok->astOperand1(), start, scope->bodyEnd);
706+
// reading another member of the same union in the rhs is a use through aliasing
707+
if (nextAssign && fwdAnalysis.hasOperand(nextAssign->astOperand2(), tokenToCheck))
708+
nextAssign = nullptr;
709+
}
706710

707711
if (!nextAssign)
708712
continue;
@@ -3055,6 +3059,16 @@ void CheckOtherImpl::checkDuplicateExpression()
30553059
checkDuplicate(ast1->astOperand1(), tok->astOperand2(), ast1);
30563060
ast1 = ast1->astOperand1();
30573061
}
3062+
if (tok->str() != "=") {
3063+
const Token* par = tok->astParent();
3064+
while (par && tok->str() == par->str() && precedes(par->astOperand1(), tok)) { // chain of identical operators with parentheses
3065+
checkDuplicate(par->astOperand1(), tok->astOperand1(), par);
3066+
checkDuplicate(par->astOperand1(), tok->astOperand2(), par);
3067+
checkDuplicate(par->astOperand2(), tok->astOperand1(), par);
3068+
checkDuplicate(par->astOperand2(), tok->astOperand2(), par);
3069+
par = par->astParent();
3070+
}
3071+
}
30583072
}
30593073
}
30603074
} else if (tok->astOperand1() && tok->astOperand2() && tok->str() == ":" && tok->astParent() && tok->astParent()->str() == "?") {

lib/checkunusedvar.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1676,6 +1676,27 @@ void CheckUnusedVarImpl::checkStructMemberUsage()
16761676
if (use)
16771677
break;
16781678
}
1679+
// Class used in template with unknown definition
1680+
if (Token::Match(tok, "%name% <") && tok->linkAt(1)) {
1681+
if (tok->function())
1682+
continue;
1683+
if (tok->type() && tok->type()->classScope)
1684+
continue;
1685+
const Token *start = tok;
1686+
while (Token::Match(start->tokAt(-2), "%name% ::"))
1687+
start = start->tokAt(-2);
1688+
if (mSettings.library.detectContainer(start))
1689+
continue;
1690+
const Token *end = tok->linkAt(1);
1691+
for (; tok != end; tok = tok->next()) {
1692+
if (tok->type() && tok->type()->classScope == &scope) {
1693+
use = true;
1694+
break;
1695+
}
1696+
}
1697+
if (use)
1698+
break;
1699+
}
16791700
if (tok->variable() != &var)
16801701
continue;
16811702
if (tok != var.nameToken()) {

0 commit comments

Comments
 (0)