Skip to content

Commit c49dfb6

Browse files
authored
fixed danmar#1059/#14519 - extract configurations for compound preprocessor checks with operators (danmar#8066)
1 parent 64abf20 commit c49dfb6

File tree

3 files changed

+300
-45
lines changed

3 files changed

+300
-45
lines changed

lib/preprocessor.cpp

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "errorlogger.h"
2323
#include "errortypes.h"
2424
#include "library.h"
25+
#include "mathlib.h"
2526
#include "path.h"
2627
#include "platform.h"
2728
#include "settings.h"
@@ -420,17 +421,21 @@ static std::string readcondition(const simplecpp::Token *iftok, const std::set<s
420421

421422
if (len == 3 && cond->name && (next1->str() == "==" || next1->str() == "<=" || next1->str() == ">=") && next2->number) {
422423
if (defined.find(cond->str()) == defined.end())
423-
return cond->str() + '=' + cond->next->next->str();
424+
return cond->str() + '=' + next1->next->str();
424425
}
425426

427+
const auto lessGreaterThanConfig = [](const simplecpp::Token* dtok, const simplecpp::Token* ctok) {
428+
auto v = MathLib::toBigNumber(ctok->next->str());
429+
if (ctok->op == '<')
430+
v -= 1;
431+
else
432+
v += 1;
433+
return dtok->str() + '=' + std::to_string(v);
434+
};
435+
426436
if (len == 3 && cond->name && (next1->op == '<' || next1->op == '>') && next2->number) {
427437
if (defined.find(cond->str()) == defined.end()) {
428-
int v = strToInt<int>(cond->next->next->str());
429-
if (next1->op == '<')
430-
v -= 1;
431-
else
432-
v += 1;
433-
return cond->str() + '=' + std::to_string(v);
438+
return lessGreaterThanConfig(cond, next1);
434439
}
435440
}
436441

@@ -447,22 +452,40 @@ static std::string readcondition(const simplecpp::Token *iftok, const std::set<s
447452
configset.insert(cond->next->str() + "=0");
448453
continue;
449454
}
450-
if (cond->str() != "defined")
455+
if (cond->str() == "==" || cond->str() == "<=" || cond->str() == ">=") {
456+
if (cond->next->number) {
457+
const simplecpp::Token *dtok = cond->previous;
458+
if (sameline(iftok,dtok) && dtok->name && defined.find(dtok->str()) == defined.end() && undefined.find(dtok->str()) == undefined.end())
459+
configset.insert(dtok->str() + '=' + cond->next->str());
460+
}
451461
continue;
452-
const simplecpp::Token *dtok = cond->next;
453-
if (!dtok)
454-
break;
455-
if (dtok->op == '(')
456-
dtok = dtok->next;
457-
458-
if (sameline(iftok,dtok) && dtok->name && defined.find(dtok->str()) == defined.end() && undefined.find(dtok->str()) == undefined.end()) {
459-
if (!isNotDefinedMacro) {
460-
configset.insert(dtok->str() + "=" + dtok->str()); // if defined is set to itself.
461-
} else {
462-
configset.insert(dtok->str());
462+
}
463+
if (cond->op == '<' || cond->op == '>') {
464+
if (cond->next->number) {
465+
const simplecpp::Token *dtok = cond->previous;
466+
if (sameline(iftok,dtok) && dtok->name && defined.find(dtok->str()) == defined.end() && undefined.find(dtok->str()) == undefined.end()) {
467+
configset.insert(lessGreaterThanConfig(dtok, cond));
468+
}
463469
}
470+
continue;
471+
}
472+
if (cond->str() == "defined") {
473+
const simplecpp::Token *dtok = cond->next;
474+
if (!dtok)
475+
break;
476+
if (dtok->op == '(')
477+
dtok = dtok->next;
478+
479+
if (sameline(iftok,dtok) && dtok->name && defined.find(dtok->str()) == defined.end() && undefined.find(dtok->str()) == undefined.end()) {
480+
if (!isNotDefinedMacro) {
481+
configset.insert(dtok->str() + "=" + dtok->str()); // if defined is set to itself.
482+
} else {
483+
configset.insert(dtok->str());
484+
}
485+
isNotDefinedMacro = false;
486+
}
487+
continue;
464488
}
465-
isNotDefinedMacro = false;
466489
}
467490
std::string cfgStr;
468491
for (const std::string &s : configset) {

test/cfg/std.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
88
//
99

10-
// cppcheck-suppress-file valueFlowBailout
10+
// cppcheck-suppress-file [valueFlowBailout,purgedConfiguration]
1111

1212
#include <string.h>
1313
#include <stdio.h>

test/testpreprocessor.cpp

Lines changed: 256 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,15 @@ class TestPreprocessor : public TestFixture {
319319
TEST_CASE(getConfigs11); // #9832 - include guards
320320
TEST_CASE(getConfigs12); // #14222
321321
TEST_CASE(getConfigs13); // #14222
322-
TEST_CASE(getConfigs14); // #1059
323-
TEST_CASE(getConfigs15); // #1059
324-
TEST_CASE(getConfigs16); // #1059
325-
TEST_CASE(getConfigs17); // #1059
322+
TEST_CASE(getConfigs_gte); // #1059
323+
TEST_CASE(getConfigs_lte); // #1059
324+
TEST_CASE(getConfigs_gt); // #1059
325+
TEST_CASE(getConfigs_lt); // #1059
326+
TEST_CASE(getConfigs_eq_compound); // #1059
327+
TEST_CASE(getConfigs_gte_compound); // #1059
328+
TEST_CASE(getConfigs_lte_compound); // #1059
329+
TEST_CASE(getConfigs_gt_compound); // #1059
330+
TEST_CASE(getConfigs_lt_compound); // #1059
326331
TEST_CASE(getConfigsError);
327332

328333
TEST_CASE(getConfigsD1);
@@ -2331,32 +2336,259 @@ class TestPreprocessor : public TestFixture {
23312336
ASSERT_EQUALS("\n", getConfigsStr(filedata, nullptr, "gnu.cfg"));
23322337
}
23332338

2334-
void getConfigs14() { // #1059
2335-
const char filedata[] = "#if A >= 1\n"
2336-
"1\n"
2337-
"#endif\n";
2338-
ASSERT_EQUALS("\nA=1\n", getConfigsStr(filedata));
2339+
void getConfigs_gte() { // #1059
2340+
{
2341+
const char filedata[] = "#if A >= 1\n"
2342+
"1\n"
2343+
"#endif\n";
2344+
ASSERT_EQUALS("\nA=1\n", getConfigsStr(filedata));
2345+
}
2346+
{
2347+
const char filedata[] = "#if A >= 201112L\n"
2348+
"1\n"
2349+
"#endif\n";
2350+
ASSERT_EQUALS("\nA=201112L\n", getConfigsStr(filedata));
2351+
}
2352+
{
2353+
const char filedata[] = "#if A >= 12147483647\n"
2354+
"1\n"
2355+
"#endif\n";
2356+
ASSERT_EQUALS("\nA=12147483647\n", getConfigsStr(filedata));
2357+
}
23392358
}
23402359

2341-
void getConfigs15() { // #1059
2342-
const char filedata[] = "#if A <= 1\n"
2343-
"1\n"
2344-
"#endif\n";
2345-
ASSERT_EQUALS("\nA=1\n", getConfigsStr(filedata));
2360+
void getConfigs_lte() { // #1059
2361+
{
2362+
const char filedata[] = "#if A <= 1\n"
2363+
"1\n"
2364+
"#endif\n";
2365+
ASSERT_EQUALS("\nA=1\n", getConfigsStr(filedata));
2366+
}
2367+
{
2368+
const char filedata[] = "#if A <= 201112L\n"
2369+
"1\n"
2370+
"#endif\n";
2371+
ASSERT_EQUALS("\nA=201112L\n", getConfigsStr(filedata));
2372+
}
2373+
{
2374+
const char filedata[] = "#if A <= 12147483647\n"
2375+
"1\n"
2376+
"#endif\n";
2377+
ASSERT_EQUALS("\nA=12147483647\n", getConfigsStr(filedata));
2378+
}
23462379
}
23472380

2348-
void getConfigs16() { // #1059
2349-
const char filedata[] = "#if A > 1\n"
2350-
"1\n"
2351-
"#endif\n";
2352-
ASSERT_EQUALS("\nA=2\n", getConfigsStr(filedata));
2381+
void getConfigs_gt() { // #1059
2382+
{
2383+
const char filedata[] = "#if A > 1\n"
2384+
"1\n"
2385+
"#endif\n";
2386+
ASSERT_EQUALS("\nA=2\n", getConfigsStr(filedata));
2387+
}
2388+
{
2389+
const char filedata[] = "#if A > 1L\n"
2390+
"1\n"
2391+
"#endif\n";
2392+
ASSERT_EQUALS("\nA=2\n", getConfigsStr(filedata));
2393+
}
2394+
{
2395+
const char filedata[] = "#if A > 1U\n"
2396+
"1\n"
2397+
"#endif\n";
2398+
ASSERT_EQUALS("\nA=2\n", getConfigsStr(filedata));
2399+
}
2400+
{
2401+
const char filedata[] = "#if A > 1UL\n"
2402+
"1\n"
2403+
"#endif\n";
2404+
ASSERT_EQUALS("\nA=2\n", getConfigsStr(filedata));
2405+
}
2406+
{
2407+
const char filedata[] = "#if A > 1Z\n"
2408+
"1\n"
2409+
"#endif\n";
2410+
ASSERT_EQUALS("\nA=2\n", getConfigsStr(filedata));
2411+
}
2412+
{
2413+
const char filedata[] = "#if A > 0x1\n"
2414+
"1\n"
2415+
"#endif\n";
2416+
ASSERT_EQUALS("\nA=2\n", getConfigsStr(filedata));
2417+
}
2418+
{
2419+
const char filedata[] = "#if A > 01\n"
2420+
"1\n"
2421+
"#endif\n";
2422+
ASSERT_EQUALS("\nA=2\n", getConfigsStr(filedata));
2423+
}
2424+
{
2425+
const char filedata[] = "#if A > 0b1\n"
2426+
"1\n"
2427+
"#endif\n";
2428+
ASSERT_EQUALS("\nA=2\n", getConfigsStr(filedata));
2429+
}
2430+
{
2431+
const char filedata[] = "#if A > 1t\n"
2432+
"1\n"
2433+
"#endif\n";
2434+
ASSERT_THROW_INTERNAL_EQUALS(getConfigsStr(filedata), INTERNAL, "Internal Error. MathLib::toBigNumber: input was not completely consumed: 1t");
2435+
}
2436+
{
2437+
const char filedata[] = "#if A > 1.0\n"
2438+
"1\n"
2439+
"#endif\n";
2440+
TODO_ASSERT_THROW(getConfigsStr(filedata), InternalError); // floating point literals are not allowed
2441+
}
2442+
{
2443+
const char filedata[] = "#if A > 12147483647\n"
2444+
"1\n"
2445+
"#endif\n";
2446+
ASSERT_EQUALS("\nA=12147483648\n", getConfigsStr(filedata));
2447+
}
23532448
}
23542449

2355-
void getConfigs17() { // #1059
2356-
const char filedata[] = "#if A < 1\n"
2357-
"1\n"
2358-
"#endif\n";
2359-
ASSERT_EQUALS("\nA=0\n", getConfigsStr(filedata));
2450+
void getConfigs_lt() { // #1059
2451+
{
2452+
const char filedata[] = "#if A < 1\n"
2453+
"1\n"
2454+
"#endif\n";
2455+
ASSERT_EQUALS("\nA=0\n", getConfigsStr(filedata));
2456+
}
2457+
{
2458+
const char filedata[] = "#if A < 1L\n"
2459+
"1\n"
2460+
"#endif\n";
2461+
ASSERT_EQUALS("\nA=0\n", getConfigsStr(filedata));
2462+
}
2463+
{
2464+
const char filedata[] = "#if A < 1U\n"
2465+
"1\n"
2466+
"#endif\n";
2467+
ASSERT_EQUALS("\nA=0\n", getConfigsStr(filedata));
2468+
}
2469+
{
2470+
const char filedata[] = "#if A < 1UL\n"
2471+
"1\n"
2472+
"#endif\n";
2473+
ASSERT_EQUALS("\nA=0\n", getConfigsStr(filedata));
2474+
}
2475+
{
2476+
const char filedata[] = "#if A < 1Z\n"
2477+
"1\n"
2478+
"#endif\n";
2479+
ASSERT_EQUALS("\nA=0\n", getConfigsStr(filedata));
2480+
}
2481+
{
2482+
const char filedata[] = "#if A < 0x1\n"
2483+
"1\n"
2484+
"#endif\n";
2485+
ASSERT_EQUALS("\nA=0\n", getConfigsStr(filedata));
2486+
}
2487+
{
2488+
const char filedata[] = "#if A < 01\n"
2489+
"1\n"
2490+
"#endif\n";
2491+
ASSERT_EQUALS("\nA=0\n", getConfigsStr(filedata));
2492+
}
2493+
{
2494+
const char filedata[] = "#if A < 0b1\n"
2495+
"1\n"
2496+
"#endif\n";
2497+
ASSERT_EQUALS("\nA=0\n", getConfigsStr(filedata));
2498+
}
2499+
{
2500+
const char filedata[] = "#if A < 1t\n"
2501+
"1\n"
2502+
"#endif\n";
2503+
ASSERT_THROW_INTERNAL_EQUALS(getConfigsStr(filedata), INTERNAL, "Internal Error. MathLib::toBigNumber: input was not completely consumed: 1t");
2504+
}
2505+
{
2506+
const char filedata[] = "#if A < 1.0\n"
2507+
"1\n"
2508+
"#endif\n";
2509+
TODO_ASSERT_THROW(getConfigsStr(filedata), InternalError); // floating point literals are not allowed
2510+
}
2511+
{
2512+
const char filedata[] = "#if A < 12147483647\n"
2513+
"1\n"
2514+
"#endif\n";
2515+
ASSERT_EQUALS("\nA=12147483646\n", getConfigsStr(filedata));
2516+
}
2517+
}
2518+
2519+
void getConfigs_eq_compound() { // #1059
2520+
{
2521+
const char filedata[] = "#if A == 1 && defined(B)\n"
2522+
"1\n"
2523+
"#endif\n";
2524+
ASSERT_EQUALS("\nA=1;B=B\n", getConfigsStr(filedata));
2525+
}
2526+
{
2527+
const char filedata[] = "#if A == 201112L && defined(B)\n"
2528+
"1\n"
2529+
"#endif\n";
2530+
ASSERT_EQUALS("\nA=201112L;B=B\n", getConfigsStr(filedata));
2531+
}
2532+
}
2533+
2534+
void getConfigs_gte_compound() { // #1059
2535+
{
2536+
const char filedata[] = "#if A >= 1 && defined(B)\n"
2537+
"1\n"
2538+
"#endif\n";
2539+
ASSERT_EQUALS("\nA=1;B=B\n", getConfigsStr(filedata));
2540+
}
2541+
{
2542+
const char filedata[] = "#if A >= 201112L && defined(B)\n"
2543+
"1\n"
2544+
"#endif\n";
2545+
ASSERT_EQUALS("\nA=201112L;B=B\n", getConfigsStr(filedata));
2546+
}
2547+
}
2548+
2549+
void getConfigs_lte_compound() { // #1059
2550+
{
2551+
const char filedata[] = "#if A <= 1 && defined(B)\n"
2552+
"1\n"
2553+
"#endif\n";
2554+
ASSERT_EQUALS("\nA=1;B=B\n", getConfigsStr(filedata));
2555+
}
2556+
{
2557+
const char filedata[] = "#if A <= 201112L && defined(B)\n"
2558+
"1\n"
2559+
"#endif\n";
2560+
ASSERT_EQUALS("\nA=201112L;B=B\n", getConfigsStr(filedata));
2561+
}
2562+
}
2563+
2564+
void getConfigs_gt_compound() { // #1059
2565+
{
2566+
const char filedata[] = "#if A > 1 && defined(B)\n"
2567+
"1\n"
2568+
"#endif\n";
2569+
ASSERT_EQUALS("\nA=2;B=B\n", getConfigsStr(filedata));
2570+
}
2571+
{
2572+
const char filedata[] = "#if A > 201112L && defined(B)\n"
2573+
"1\n"
2574+
"#endif\n";
2575+
ASSERT_EQUALS("\nA=201113;B=B\n", getConfigsStr(filedata));
2576+
}
2577+
}
2578+
2579+
void getConfigs_lt_compound() { // #1059
2580+
{
2581+
const char filedata[] = "#if A < 1 && defined(B)\n"
2582+
"1\n"
2583+
"#endif\n";
2584+
ASSERT_EQUALS("\nA=0;B=B\n", getConfigsStr(filedata));
2585+
}
2586+
{
2587+
const char filedata[] = "#if A < 201112L && defined(B)\n"
2588+
"1\n"
2589+
"#endif\n";
2590+
ASSERT_EQUALS("\nA=201111;B=B\n", getConfigsStr(filedata));
2591+
}
23602592
}
23612593

23622594
void getConfigsError() {

0 commit comments

Comments
 (0)