/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2025 Cppcheck team.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "checktype.h"
#include "errortypes.h"
#include "fixture.h"
#include "helpers.h"
#include "platform.h"
#include "settings.h"
#include "standards.h"
#include
#include
class TestType : public TestFixture {
public:
TestType() : TestFixture("TestType") {}
private:
void run() override {
TEST_CASE(checkTooBigShift_Unix32);
mNewTemplate = true;
TEST_CASE(checkIntegerOverflow);
TEST_CASE(signConversion);
TEST_CASE(longCastAssign);
TEST_CASE(longCastReturn);
TEST_CASE(checkFloatToIntegerOverflow);
TEST_CASE(integerOverflow); // #11794
TEST_CASE(shiftTooManyBits); // #11496
}
struct CheckOptions
{
CheckOptions() = default;
const Settings* settings = nullptr;
Standards::cppstd_t standard = Standards::cppstd_t::CPP11;
};
#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(options.settings ? *options.settings : settingsDefault).severity(Severity::warning).severity(Severity::portability).cpp(options.standard).build();
// Tokenize..
SimpleTokenizer tokenizer(settings1, *this);
ASSERT_LOC(tokenizer.tokenize(code), file, line);
// Check..
runChecks(tokenizer, this);
}
// TODO: get rid of this
void check_(const char* file, int line, const std::string& code, const CheckOptions& options = make_default_obj()) {
const Settings settings1 = settingsBuilder(options.settings ? *options.settings : settingsDefault).severity(Severity::warning).severity(Severity::portability).cpp(options.standard).build();
// Tokenize..
SimpleTokenizer tokenizer(settings1, *this);
ASSERT_LOC(tokenizer.tokenize(code), file, line);
// Check..
runChecks(tokenizer, this);
}
struct CheckPOptions
{
CheckPOptions() = default;
const Settings* settings = nullptr;
bool cpp = true;
};
#define checkP(...) checkP_(__FILE__, __LINE__, __VA_ARGS__)
template
void checkP_(const char* file, int line, const char (&code)[size], const CheckPOptions& options = make_default_obj()) {
const Settings settings1 = settingsBuilder(options.settings ? *options.settings : settingsDefault).severity(Severity::warning).severity(Severity::portability).build();
SimpleTokenizer2 tokenizer(settings1, *this, code, options.cpp ? "test.cpp" : "test.c");
// Tokenizer..
ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line);
// Check..
runChecks(tokenizer, this);
}
void checkTooBigShift_Unix32() {
const Settings settings = settingsBuilder().platform(Platform::Type::Unix32).build();
// unsigned types getting promoted to int sizeof(int) = 4 bytes
// and unsigned types having already a size of 4 bytes
{
const std::string types[] = {"unsigned char", /*[unsigned]*/ "char", "bool", "unsigned short", "unsigned int", "unsigned long"};
for (const std::string& type : types) {
check(type + " f(" + type +" x) { return x