Skip to content

Commit a8fd5cb

Browse files
authored
added entrypoint to library configuration and got rid of hard-coded ones (#4691)
1 parent 3076f9d commit a8fd5cb

12 files changed

+153
-43
lines changed

cfg/cppcheck-cfg.rng

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,9 @@
625625
</oneOrMore>
626626
</element>
627627

628+
<element name="entrypoint">
629+
<attribute name="name"><text/></attribute>
630+
</element>
628631
</choice>
629632
</zeroOrMore>
630633
</element>

cfg/gnu.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,4 +1731,6 @@
17311731
<define name="STDIN_FILENO" value="0"/>
17321732
<define name="STDOUT_FILENO" value="1"/>
17331733
<define name="STDERR_FILENO" value="2"/>
1734+
<entrypoint name="_init"/>
1735+
<entrypoint name="_fini"/>
17341736
</def>

cfg/windows.cfg

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17938,4 +17938,17 @@ HFONT CreateFont(
1793817938
<define name="UNREFERENCED_PARAMETER(P)" value="((void)(P))"/>
1793917939
<define name="DBG_UNREFERENCED_PARAMETER(P)" value="((void)(P))"/>
1794017940
<define name="DBG_UNREFERENCED_LOCAL_VARIABLE(P)" value="((void)(P))"/>
17941+
<!-- https://learn.microsoft.com/en-us/cpp/build/reference/entry-entry-point-symbol -->
17942+
<entrypoint name="mainCRTStartup"/>
17943+
<entrypoint name="WinMain"/>
17944+
<entrypoint name="WinMainCRTStartup"/>
17945+
<entrypoint name="DllMain"/>
17946+
<entrypoint name="_DllMainCRTStartup"/>
17947+
<!-- TODO: these are UNICODE-specific -->
17948+
<entrypoint name="wmain"/>
17949+
<entrypoint name="wmainCRTStartup"/>
17950+
<entrypoint name="wWinMain"/>
17951+
<entrypoint name="wWinMainCRTStartup"/>
17952+
<!-- TODO: this is actually a define -->
17953+
<entrypoint name="_tmain"/>
1794117954
</def>

lib/checkexceptionsafety.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,9 +322,7 @@ void CheckExceptionSafety::unhandledExceptionSpecification()
322322

323323
for (const Scope * scope : symbolDatabase->functionScopes) {
324324
// only check functions without exception specification
325-
if (scope->function && !scope->function->isThrow() &&
326-
scope->className != "main" && scope->className != "wmain" &&
327-
scope->className != "_tmain" && scope->className != "WinMain") {
325+
if (scope->function && !scope->function->isThrow() && !mSettings->library.isentrypoint(scope->className)) {
328326
for (const Token *tok = scope->function->functionScope->bodyStart->next();
329327
tok != scope->function->functionScope->bodyEnd; tok = tok->next()) {
330328
if (tok->str() == "try") {

lib/checkunusedfunctions.cpp

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,6 @@ static bool isOperatorFunction(const std::string & funcName)
305305
return std::find(additionalOperators.cbegin(), additionalOperators.cend(), funcName.substr(operatorPrefix.length())) != additionalOperators.cend();
306306
}
307307

308-
309-
310308
bool CheckUnusedFunctions::check(ErrorLogger * const errorLogger, const Settings& settings) const
311309
{
312310
using ErrorParams = std::tuple<std::string, unsigned int, std::string>;
@@ -316,8 +314,7 @@ bool CheckUnusedFunctions::check(ErrorLogger * const errorLogger, const Settings
316314
const FunctionUsage &func = it->second;
317315
if (func.usedOtherFile || func.filename.empty())
318316
continue;
319-
if (it->first == "main" ||
320-
(settings.isWindowsPlatform() && (it->first == "WinMain" || it->first == "_tmain")))
317+
if (settings.library.isentrypoint(it->first))
321318
continue;
322319
if (!func.usedSameFile) {
323320
if (isOperatorFunction(it->first))
@@ -401,7 +398,7 @@ namespace {
401398
};
402399
}
403400

404-
void CheckUnusedFunctions::analyseWholeProgram(ErrorLogger * const errorLogger, const std::string &buildDir)
401+
void CheckUnusedFunctions::analyseWholeProgram(const Settings &settings, ErrorLogger * const errorLogger, const std::string &buildDir)
405402
{
406403
std::map<std::string, Location> decls;
407404
std::set<std::string> calls;
@@ -453,11 +450,7 @@ void CheckUnusedFunctions::analyseWholeProgram(ErrorLogger * const errorLogger,
453450
for (std::map<std::string, Location>::const_iterator decl = decls.cbegin(); decl != decls.cend(); ++decl) {
454451
const std::string &functionName = decl->first;
455452

456-
// TODO: move to configuration files
457-
// TODO: WinMain, wmain and _tmain only apply to Windows code
458-
// TODO: also skip other known entry functions i.e. annotated with "constructor" and "destructor" attributes
459-
if (functionName == "main" || functionName == "WinMain" || functionName == "wmain" || functionName == "_tmain" ||
460-
functionName == "if")
453+
if (settings.library.isentrypoint(functionName))
461454
continue;
462455

463456
if (calls.find(functionName) == calls.end() && !isOperatorFunction(functionName)) {

lib/checkunusedfunctions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class CPPCHECKLIB CheckUnusedFunctions : public Check {
7676
std::string analyzerInfo() const;
7777

7878
/** @brief Combine and analyze all analyzerInfos for all TUs */
79-
static void analyseWholeProgram(ErrorLogger * const errorLogger, const std::string &buildDir);
79+
static void analyseWholeProgram(const Settings &settings, ErrorLogger * const errorLogger, const std::string &buildDir);
8080

8181
private:
8282

lib/cppcheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1764,7 +1764,7 @@ void CppCheck::analyseWholeProgram(const std::string &buildDir, const std::map<s
17641764
return;
17651765
}
17661766
if (mSettings.checks.isEnabled(Checks::unusedFunction))
1767-
CheckUnusedFunctions::analyseWholeProgram(this, buildDir);
1767+
CheckUnusedFunctions::analyseWholeProgram(mSettings, this, buildDir);
17681768
std::list<Check::FileInfo*> fileInfoList;
17691769
CTU::FileInfo ctuFileInfo;
17701770

lib/importproject.cpp

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -533,28 +533,37 @@ namespace {
533533
if (condAttr)
534534
condition = condAttr;
535535
for (const tinyxml2::XMLElement *e1 = idg->FirstChildElement(); e1; e1 = e1->NextSiblingElement()) {
536-
if (std::strcmp(e1->Name(), "ClCompile") != 0)
537-
continue;
538-
enhancedInstructionSet = "StreamingSIMDExtensions2";
539-
for (const tinyxml2::XMLElement *e = e1->FirstChildElement(); e; e = e->NextSiblingElement()) {
540-
if (e->GetText()) {
541-
if (std::strcmp(e->Name(), "PreprocessorDefinitions") == 0)
542-
preprocessorDefinitions = e->GetText();
543-
else if (std::strcmp(e->Name(), "AdditionalIncludeDirectories") == 0) {
544-
if (!additionalIncludePaths.empty())
545-
additionalIncludePaths += ';';
546-
additionalIncludePaths += e->GetText();
547-
} else if (std::strcmp(e->Name(), "LanguageStandard") == 0) {
548-
if (std::strcmp(e->GetText(), "stdcpp14") == 0)
549-
cppstd = Standards::CPP14;
550-
else if (std::strcmp(e->GetText(), "stdcpp17") == 0)
551-
cppstd = Standards::CPP17;
552-
else if (std::strcmp(e->GetText(), "stdcpp20") == 0)
553-
cppstd = Standards::CPP20;
554-
else if (std::strcmp(e->GetText(), "stdcpplatest") == 0)
555-
cppstd = Standards::CPPLatest;
556-
} else if (std::strcmp(e->Name(), "EnableEnhancedInstructionSet") == 0) {
557-
enhancedInstructionSet = e->GetText();
536+
if (std::strcmp(e1->Name(), "ClCompile") == 0) {
537+
enhancedInstructionSet = "StreamingSIMDExtensions2";
538+
for (const tinyxml2::XMLElement *e = e1->FirstChildElement(); e; e = e->NextSiblingElement()) {
539+
if (e->GetText()) {
540+
if (std::strcmp(e->Name(), "PreprocessorDefinitions") == 0)
541+
preprocessorDefinitions = e->GetText();
542+
else if (std::strcmp(e->Name(), "AdditionalIncludeDirectories") == 0) {
543+
if (!additionalIncludePaths.empty())
544+
additionalIncludePaths += ';';
545+
additionalIncludePaths += e->GetText();
546+
} else if (std::strcmp(e->Name(), "LanguageStandard") == 0) {
547+
if (std::strcmp(e->GetText(), "stdcpp14") == 0)
548+
cppstd = Standards::CPP14;
549+
else if (std::strcmp(e->GetText(), "stdcpp17") == 0)
550+
cppstd = Standards::CPP17;
551+
else if (std::strcmp(e->GetText(), "stdcpp20") == 0)
552+
cppstd = Standards::CPP20;
553+
else if (std::strcmp(e->GetText(), "stdcpplatest") == 0)
554+
cppstd = Standards::CPPLatest;
555+
} else if (std::strcmp(e->Name(), "EnableEnhancedInstructionSet") == 0) {
556+
enhancedInstructionSet = e->GetText();
557+
}
558+
}
559+
}
560+
}
561+
else if (std::strcmp(e1->Name(), "Link") == 0) {
562+
for (const tinyxml2::XMLElement *e = e1->FirstChildElement(); e; e = e->NextSiblingElement()) {
563+
if (!e->GetText())
564+
continue;
565+
if (std::strcmp(e->Name(), "EntryPointSymbol") == 0) {
566+
entryPointSymbol = e->GetText();
558567
}
559568
}
560569
}
@@ -595,6 +604,7 @@ namespace {
595604
std::string enhancedInstructionSet;
596605
std::string preprocessorDefinitions;
597606
std::string additionalIncludePaths;
607+
std::string entryPointSymbol; // TODO: use this
598608
Standards::cppstd_t cppstd = Standards::CPPLatest;
599609
};
600610
}

lib/library.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,13 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc)
643643
}
644644
}
645645

646+
else if (nodename == "entrypoint") {
647+
const char * const type_name = node->Attribute("name");
648+
if (type_name == nullptr)
649+
return Error(ErrorCode::MISSING_ATTRIBUTE, "name");
650+
mEntrypoints.emplace(type_name);
651+
}
652+
646653
else
647654
unknown_elements.insert(nodename);
648655
}

lib/library.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <set>
3333
#include <string>
3434
#include <unordered_map>
35+
#include <unordered_set>
3536
#include <utility>
3637
#include <vector>
3738

@@ -476,6 +477,10 @@ class CPPCHECKLIB Library {
476477
return -1;
477478
}
478479

480+
bool isentrypoint(const std::string &func) const {
481+
return func == "main" || mEntrypoints.find(func) != mEntrypoints.end();
482+
}
483+
479484
std::vector<std::string> defines; // to provide some library defines
480485

481486
struct SmartPointer {
@@ -643,6 +648,7 @@ class CPPCHECKLIB Library {
643648
std::map<std::string, Platform> mPlatforms; // platform dependent typedefs
644649
std::map<std::pair<std::string,std::string>, TypeCheck> mTypeChecks;
645650
std::unordered_map<std::string, NonOverlappingData> mNonOverlappingData;
651+
std::unordered_set<std::string> mEntrypoints;
646652

647653
const ArgumentChecks * getarg(const Token *ftok, int argnr) const;
648654

0 commit comments

Comments
 (0)