Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/cppcheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string
std::vector<std::string> files;
simplecpp::TokenList tokens(*fileStream, files, file.spath());
if (analyzerInformation) {
const Preprocessor preprocessor(mSettings, mErrorLogger);
const Preprocessor preprocessor(mSettings, mErrorLogger, Standards::Language::C);
hash = calculateHash(preprocessor, tokens, mSettings, mSuppressions);
}
tokenlist.createTokens(std::move(tokens));
Expand All @@ -926,7 +926,7 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string
std::vector<std::string> files;
simplecpp::TokenList tokens(file.spath(), files);
if (analyzerInformation) {
const Preprocessor preprocessor(mSettings, mErrorLogger);
const Preprocessor preprocessor(mSettings, mErrorLogger, file.lang());
hash = calculateHash(preprocessor, tokens, mSettings, mSuppressions);
}
tokenlist.createTokens(std::move(tokens));
Expand Down Expand Up @@ -973,7 +973,7 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string
return mLogger->exitcode();
}

Preprocessor preprocessor(mSettings, mErrorLogger);
Preprocessor preprocessor(mSettings, mErrorLogger, file.lang());

if (!preprocessor.loadFiles(tokens1, files))
return mLogger->exitcode();
Expand Down
20 changes: 12 additions & 8 deletions lib/preprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

#include <algorithm>
#include <array>
#include <cassert>
#include <cstddef>
#include <iterator>
#include <sstream>
Expand Down Expand Up @@ -63,8 +64,13 @@ Directive::DirectiveToken::DirectiveToken(const simplecpp::Token & _tok) :

char Preprocessor::macroChar = char(1);

Preprocessor::Preprocessor(const Settings& settings, ErrorLogger &errorLogger) : mSettings(settings), mErrorLogger(errorLogger)
{}
Preprocessor::Preprocessor(const Settings& settings, ErrorLogger &errorLogger, Standards::Language lang)
: mSettings(settings)
, mErrorLogger(errorLogger)
, mLang(lang)
{
assert(mLang != Standards::Language::None);
}

Preprocessor::~Preprocessor()
{
Expand Down Expand Up @@ -688,7 +694,7 @@ static void splitcfg(const std::string &cfg, std::list<std::string> &defines, co
}
}

static simplecpp::DUI createDUI(const Settings &mSettings, const std::string &cfg, const std::string &filename)
static simplecpp::DUI createDUI(const Settings &mSettings, const std::string &cfg, Standards::Language lang)
{
// TODO: make it possible to specify platform-dependent sizes
simplecpp::DUI dui;
Expand Down Expand Up @@ -716,8 +722,6 @@ static simplecpp::DUI createDUI(const Settings &mSettings, const std::string &cf
dui.includePaths = mSettings.includePaths; // -I
dui.includes = mSettings.userIncludes; // --include
// TODO: use mSettings.standards.stdValue instead
// TODO: error out on unknown language?
const Standards::Language lang = Path::identify(filename, mSettings.cppHeaderProbe);
if (lang == Standards::Language::CPP) {
dui.std = mSettings.standards.getCPP();
splitcfg(mSettings.platform.getLimitsDefines(Standards::getCPP(dui.std)), dui.defines, "");
Expand Down Expand Up @@ -773,7 +777,7 @@ void Preprocessor::handleErrors(const simplecpp::OutputList& outputList, bool th

bool Preprocessor::loadFiles(const simplecpp::TokenList &rawtokens, std::vector<std::string> &files)
{
const simplecpp::DUI dui = createDUI(mSettings, "", files[0]);
const simplecpp::DUI dui = createDUI(mSettings, "", mLang);

simplecpp::OutputList outputList;
mTokenLists = simplecpp::load(rawtokens, files, dui, &outputList);
Expand Down Expand Up @@ -812,7 +816,7 @@ void Preprocessor::setPlatformInfo(simplecpp::TokenList &tokens, const Settings&

simplecpp::TokenList Preprocessor::preprocess(const simplecpp::TokenList &tokens1, const std::string &cfg, std::vector<std::string> &files, bool throwError)
{
const simplecpp::DUI dui = createDUI(mSettings, cfg, files[0]);
const simplecpp::DUI dui = createDUI(mSettings, cfg, mLang);

simplecpp::OutputList outputList;
std::list<simplecpp::MacroUsage> macroUsage;
Expand Down Expand Up @@ -927,7 +931,7 @@ void Preprocessor::missingInclude(const std::string &filename, unsigned int line

void Preprocessor::getErrorMessages(ErrorLogger &errorLogger, const Settings &settings)
{
Preprocessor preprocessor(settings, errorLogger);
Preprocessor preprocessor(settings, errorLogger, Standards::Language::CPP);
preprocessor.missingInclude("", 1, "", UserHeader);
preprocessor.missingInclude("", 1, "", SystemHeader);
preprocessor.error("", 1, "#error message"); // #error ..
Expand Down
4 changes: 3 additions & 1 deletion lib/preprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
//---------------------------------------------------------------------------

#include "config.h"
#include "standards.h"

#include <cstddef>
#include <cstdint>
Expand Down Expand Up @@ -108,7 +109,7 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor {
/** character that is inserted in expanded macros */
static char macroChar;

explicit Preprocessor(const Settings& settings, ErrorLogger &errorLogger);
explicit Preprocessor(const Settings& settings, ErrorLogger &errorLogger, Standards::Language lang);
virtual ~Preprocessor();

void inlineSuppressions(const simplecpp::TokenList &tokens, SuppressionList &suppressions);
Expand Down Expand Up @@ -180,6 +181,7 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor {

/** filename for cpp/c file - useful when reporting errors */
std::string mFile0;
Standards::Language mLang{Standards::Language::None};

/** simplecpp tracking info */
std::list<simplecpp::MacroUsage> mMacroUsage;
Expand Down
46 changes: 45 additions & 1 deletion test/cli/other_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3563,4 +3563,48 @@ def test_suppress_unmatched_wildcard_unchecked(tmp_path):
'tes?.c:-1:0: information: Unmatched suppression: id [unmatchedSuppression]',
'*:-1:0: information: Unmatched suppression: id2 [unmatchedSuppression]',
'test*.c:-1:0: information: Unmatched suppression: * [unmatchedSuppression]'
]
]


def test_preprocess_enforced_c(tmp_path): # #10989
test_file = tmp_path / 'test.cpp'
with open(test_file, 'wt') as f:
f.write(
"""#ifdef __cplusplus
#error "err"
#endif""")

args = [
'-q',
'--template=simple',
'--language=c',
str(test_file)
]

exitcode, stdout, stderr = cppcheck(args)
assert exitcode == 0, stdout if stdout else stderr
assert stdout.splitlines() == []
assert stderr.splitlines() == []


def test_preprocess_enforced_cpp(tmp_path): # #10989
test_file = tmp_path / 'test.c'
with open(test_file, 'wt') as f:
f.write(
"""#ifdef __cplusplus
#error "err"
#endif""")

args = [
'-q',
'--template=simple',
'--language=c++',
str(test_file)
]

exitcode, stdout, stderr = cppcheck(args)
assert exitcode == 0, stdout if stdout else stderr
assert stdout.splitlines() == []
assert stderr.splitlines() == [
'{}:2:2: error: #error "err" [preprocessorErrorDirective]'.format(test_file)
]
4 changes: 2 additions & 2 deletions test/helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ std::map<std::string, std::string> PreprocessorHelper::getcode(const Settings& s

std::istringstream istr(code);
simplecpp::TokenList tokens(istr, files, Path::simplifyPath(filename), &outputList);
Preprocessor preprocessor(settings, errorlogger);
Preprocessor preprocessor(settings, errorlogger, Path::identify(tokens.getFiles()[0], false));
if (inlineSuppression)
preprocessor.inlineSuppressions(tokens, *inlineSuppression);
preprocessor.removeComments(tokens);
Expand Down Expand Up @@ -168,7 +168,7 @@ void SimpleTokenizer2::preprocess(const char code[], std::vector<std::string> &f
std::istringstream istr(code);
const simplecpp::TokenList tokens1(istr, files, file0);

Preprocessor preprocessor(tokenizer.getSettings(), errorlogger);
Preprocessor preprocessor(tokenizer.getSettings(), errorlogger, Path::identify(tokens1.getFiles()[0], false));
simplecpp::TokenList tokens2 = preprocessor.preprocess(tokens1, "", files, true);

// Tokenizer..
Expand Down
33 changes: 18 additions & 15 deletions test/testpreprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "platform.h"
#include "preprocessor.h"
#include "settings.h"
#include "standards.h"
#include "suppressions.h"
#include "tokenlist.h"
#include "fixture.h"
Expand Down Expand Up @@ -54,7 +55,7 @@ class TestPreprocessor : public TestFixture {
simplecpp::OutputList outputList;
std::vector<std::string> files;
const simplecpp::TokenList tokens1 = simplecpp::TokenList(istr, files, "file.cpp", &outputList);
Preprocessor p(settingsDefault, errorLogger);
Preprocessor p(settingsDefault, errorLogger, Path::identify(tokens1.getFiles()[0], false));
simplecpp::TokenList tokens2 = p.preprocess(tokens1, "", files, true);
p.reportOutput(outputList, true);
return tokens2.stringify();
Expand Down Expand Up @@ -87,7 +88,7 @@ class TestPreprocessor : public TestFixture {
std::istringstream istr(code);
const simplecpp::TokenList tokens1(istr, files, "test.cpp");

const Preprocessor preprocessor(settingsDefault, errorLogger);
const Preprocessor preprocessor(settingsDefault, errorLogger, Path::identify(tokens1.getFiles()[0], false));
return preprocessor.getRemarkComments(tokens1);
}

Expand Down Expand Up @@ -301,11 +302,12 @@ class TestPreprocessor : public TestFixture {
settings.userDefines = arg + 2;
if (arg && std::strncmp(arg,"-U",2)==0)
settings.userUndefs.insert(arg+2);
Preprocessor preprocessor(settings, *this);
std::vector<std::string> files;
std::istringstream istr(filedata);
// TODO: this adds an empty filename
simplecpp::TokenList tokens(istr,files);
tokens.removeComments();
Preprocessor preprocessor(settings, *this, Standards::Language::C); // TODO: do we need to consider #file?
const std::set<std::string> configs = preprocessor.getConfigs(tokens);
std::string ret;
for (const std::string & config : configs)
Expand All @@ -314,11 +316,12 @@ class TestPreprocessor : public TestFixture {
}

std::size_t getHash(const char filedata[]) {
Preprocessor preprocessor(settingsDefault, *this);
std::vector<std::string> files;
std::istringstream istr(filedata);
// TODO: this adds an empty filename
simplecpp::TokenList tokens(istr,files);
tokens.removeComments();
Preprocessor preprocessor(settingsDefault, *this, Standards::Language::C); // TODO: do we need to consider #file?
return preprocessor.calculateHash(tokens, "");
}

Expand Down Expand Up @@ -478,15 +481,15 @@ class TestPreprocessor : public TestFixture {
{
const Settings settings = settingsBuilder().platform(Platform::Type::Unix32).build();
Preprocessor::setPlatformInfo(tokens, settings);
Preprocessor preprocessor(settings, *this);
Preprocessor preprocessor(settings, *this, Path::identify(tokens.getFiles()[0], false));
ASSERT_EQUALS("\n1", preprocessor.getcode(tokens, "", files, false));
}

// preprocess code with unix64 platform..
{
const Settings settings = settingsBuilder().platform(Platform::Type::Unix64).build();
Preprocessor::setPlatformInfo(tokens, settings);
Preprocessor preprocessor(settings, *this);
Preprocessor preprocessor(settings, *this, Path::identify(tokens.getFiles()[0], false));
ASSERT_EQUALS("\n\n\n2", preprocessor.getcode(tokens, "", files, false));
}
}
Expand Down Expand Up @@ -1211,7 +1214,7 @@ class TestPreprocessor : public TestFixture {
"#undef z\n"
"int z;\n"
"z = 0;\n";
ASSERT_EQUALS("\n\nint z ;\nz = 0 ;", PreprocessorHelper::getcode(settings0, *this, filedata, "", ""));
ASSERT_EQUALS("\n\nint z ;\nz = 0 ;", PreprocessorHelper::getcode(settings0, *this, filedata, "", "test.c"));
}
}

Expand Down Expand Up @@ -1629,14 +1632,14 @@ class TestPreprocessor : public TestFixture {
"#if A\n"
"FOO\n"
"#endif";
ASSERT_EQUALS("", PreprocessorHelper::getcode(settings0, *this, filedata,"",""));
ASSERT_EQUALS("", PreprocessorHelper::getcode(settings0, *this, filedata,"","test.c"));
}
{
const char filedata[] = "#define A 1\n"
"#if A==1\n"
"FOO\n"
"#endif";
ASSERT_EQUALS("\n\nFOO", PreprocessorHelper::getcode(settings0, *this, filedata,"",""));
ASSERT_EQUALS("\n\nFOO", PreprocessorHelper::getcode(settings0, *this, filedata,"","test.c"));
}
}

Expand All @@ -1646,23 +1649,23 @@ class TestPreprocessor : public TestFixture {
"#if (B==A) || (B==C)\n"
"FOO\n"
"#endif";
ASSERT_EQUALS("\n\n\nFOO", PreprocessorHelper::getcode(settings0, *this, filedata,"",""));
ASSERT_EQUALS("\n\n\nFOO", PreprocessorHelper::getcode(settings0, *this, filedata,"","test.c"));
}

void define_if3() {
const char filedata[] = "#define A 0\n"
"#if (A==0)\n"
"FOO\n"
"#endif";
ASSERT_EQUALS("\n\nFOO", PreprocessorHelper::getcode(settings0, *this, filedata,"",""));
ASSERT_EQUALS("\n\nFOO", PreprocessorHelper::getcode(settings0, *this, filedata,"","test.c"));
}

void define_if4() {
const char filedata[] = "#define X +123\n"
"#if X==123\n"
"FOO\n"
"#endif";
ASSERT_EQUALS("\n\nFOO", PreprocessorHelper::getcode(settings0, *this, filedata,"",""));
ASSERT_EQUALS("\n\nFOO", PreprocessorHelper::getcode(settings0, *this, filedata,"","test.c"));
}

void define_if5() { // #4516 - #define B (A & 0x00f0)
Expand All @@ -1672,7 +1675,7 @@ class TestPreprocessor : public TestFixture {
"#if B==0x0010\n"
"FOO\n"
"#endif";
ASSERT_EQUALS("\n\n\nFOO", PreprocessorHelper::getcode(settings0, *this, filedata,"",""));
ASSERT_EQUALS("\n\n\nFOO", PreprocessorHelper::getcode(settings0, *this, filedata,"","test.c"));
}
{
const char filedata[] = "#define A 0x00f0\n"
Expand All @@ -1681,14 +1684,14 @@ class TestPreprocessor : public TestFixture {
"#if C==0x0010\n"
"FOO\n"
"#endif";
ASSERT_EQUALS("\n\n\n\nFOO", PreprocessorHelper::getcode(settings0, *this, filedata,"",""));
ASSERT_EQUALS("\n\n\n\nFOO", PreprocessorHelper::getcode(settings0, *this, filedata,"","test.c"));
}
{
const char filedata[] = "#define A (1+A)\n" // don't hang for recursive macros
"#if A==1\n"
"FOO\n"
"#endif";
ASSERT_EQUALS("\n\nFOO", PreprocessorHelper::getcode(settings0, *this, filedata,"",""));
ASSERT_EQUALS("\n\nFOO", PreprocessorHelper::getcode(settings0, *this, filedata,"","test.c"));
}
}

Expand Down
4 changes: 2 additions & 2 deletions test/testtokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,11 +550,11 @@ class TestTokenizer : public TestFixture {
}

void directiveDump(const char filedata[], const char filename[], const Settings& settings, std::ostream& ostr) {
Preprocessor preprocessor(settings, *this);
std::istringstream istr(filedata);
simplecpp::OutputList outputList;
std::vector<std::string> files;
const simplecpp::TokenList tokens1(istr, files, filename, &outputList);
Preprocessor preprocessor(settings, *this, Path::identify(tokens1.getFiles()[0], false));
std::list<Directive> directives = preprocessor.createDirectives(tokens1);

TokenList tokenlist{&settings};
Expand Down Expand Up @@ -8573,7 +8573,7 @@ class TestTokenizerCompileLimits : public TestFixture
std::vector<std::string> files;
const simplecpp::TokenList tokens1(fin, files, "", &outputList);
const std::string filedata = tokens1.stringify();
const std::string code = PreprocessorHelper::getcode(settingsDefault, *this, filedata, "", "");
const std::string code = PreprocessorHelper::getcode(settingsDefault, *this, filedata, "", "test.c");

ASSERT_THROW_INTERNAL_EQUALS(tokenizeAndStringify(code), AST, "maximum AST depth exceeded");
}
Expand Down
2 changes: 1 addition & 1 deletion test/testtokenlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class TestTokenList : public TestFixture {
std::istringstream istr(code);
std::vector<std::string> files;
simplecpp::TokenList tokens1(istr, files, "poll.h", nullptr);
Preprocessor preprocessor(settingsDefault, *this);
Preprocessor preprocessor(settingsDefault, *this, Path::identify(tokens1.getFiles()[0], false));
simplecpp::TokenList tokensP = preprocessor.preprocess(tokens1, "", files, true);
TokenList tokenlist(&settingsDefault);
tokenlist.createTokens(std::move(tokensP)); // do not assert
Expand Down
Loading