diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index eeb19c2381c..0498a7e303d 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -150,7 +150,7 @@ namespace ValueFlow if (!tok->isTemplateArg()) value.setKnown(); setTokenValue(tok, std::move(value), settings); - } else if (tok->str() == "NULL" || (tok->isCpp() && tok->str() == "nullptr")) { + } else if (tok->str() == "NULL" || ((tok->isCpp() || settings.standards.c >= Standards::C23) && tok->str() == "nullptr")) { Value value(0); if (!tok->isTemplateArg()) value.setKnown(); diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 1e21479d5ab..1028c527275 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -183,12 +183,13 @@ class TestNullPointer : public TestFixture { CheckOptions() = default; bool inconclusive = false; bool cpp = true; + Standards::cstd_t cstd = Standards::CLatest; }; #define check(...) check_(__FILE__, __LINE__, __VA_ARGS__) template void check_(const char* file, int line, const char (&code)[size], const CheckOptions& options = make_default_obj()) { - const Settings settings1 = settingsBuilder(settings).certainty(Certainty::inconclusive, options.inconclusive).build(); + const Settings settings1 = settingsBuilder(settings).certainty(Certainty::inconclusive, options.inconclusive).c(options.cstd).build(); // Tokenize.. SimpleTokenizer tokenizer(settings1, *this, options.cpp); @@ -1331,8 +1332,11 @@ class TestNullPointer : public TestFixture { check(code); // C++ file => nullptr means NULL ASSERT_EQUALS("[test.cpp:4:11]: (error) Null pointer dereference: i [nullPointer]\n", errout_str()); - check(code, dinit(CheckOptions, $.cpp = false)); // C file => nullptr does not mean NULL + check(code, dinit(CheckOptions, $.cpp = false, $.cstd = Standards::C17)); // C17 file => nullptr does not mean NULL ASSERT_EQUALS("", errout_str()); + + check(code, dinit(CheckOptions, $.cpp = false)); + ASSERT_EQUALS("[test.c:4:11]: (error) Null pointer dereference: i [nullPointer]\n", errout_str()); } void nullpointer15() { // #3560 diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index d5a2b4f019b..86fa02b9191 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -5635,6 +5635,23 @@ class TestValueFlow : public TestFixture { value = valueOfTok(code, ", 1"); ASSERT_EQUALS(0, value.intvalue); ASSERT_EQUALS(false, value.isKnown()); + + // #13959 + const Settings settingsOld = settings; + settings = settingsBuilder(settingsOld).c(Standards::C23).build(); + code = "void f(int* p) {\n" + " if (p == nullptr)\n" + " return;\n" + " if (p) {}\n" + "}\n"; + value = valueOfTok(code, "p ) { }", &settings, /*cpp*/ false); + ASSERT_EQUALS(1, value.intvalue); + ASSERT_EQUALS(true, value.isKnown()); + + settings = settingsBuilder(settingsOld).c(Standards::C17).build(); + value = valueOfTok(code, "p ) { }", &settings, /*cpp*/ false); + ASSERT(value == ValueFlow::Value()); + settings = settingsOld; } void valueFlowSizeofForwardDeclaredEnum() {