Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable clang-analyzer #2194

Merged
merged 3 commits into from
Oct 17, 2023
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: 5 additions & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Bugprone exception escape is super unhelpful.
# NewDeleteLeaks has many false positives w.r.t smart pointers.
Checks:
-*,

Expand All @@ -10,7 +11,10 @@ Checks:
-bugprone-narrowing-conversions,
-bugprone-signed-char-misuse,

clang-analyzer-deadcode.DeadStores,
clang-analyzer-*,
-clang-analyzer-cplusplus.NewDeleteLeaks,

concurrency-*,

HeaderFilterRegex: src/include|tools/benchmark/include|tools/nodejs_api/src_cpp/include|tools/python_api/src_cpp/include|tools/rust_api/include|tools/shell/include
WarningsAsErrors: "*"
2 changes: 2 additions & 0 deletions dataset/csv-error-tests/union-no-conversion.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
"col:UNION(u UINT8, s INT8)"
a
6 changes: 3 additions & 3 deletions src/binder/bind/bind_copy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "catalog/rel_table_schema.h"
#include "common/exception/binder.h"
#include "common/exception/message.h"
#include "common/string_utils.h"
#include "common/string_format.h"
#include "common/table_type.h"
#include "parser/copy.h"

Expand Down Expand Up @@ -78,8 +78,8 @@ std::unique_ptr<BoundStatement> Binder::bindCopyFromClause(const Statement& stat
switch (tableSchema->tableType) {
case TableType::REL_GROUP:
case TableType::RDF: {
throw BinderException(StringUtils::string_format("Cannot copy into {} table with type {}.",
tableName, TableTypeUtils::toString(tableSchema->tableType)));
throw BinderException(stringFormat("Cannot copy into {} table with type {}.", tableName,
TableTypeUtils::toString(tableSchema->tableType)));
}
default:
break;
Expand Down
6 changes: 4 additions & 2 deletions src/binder/bind/bind_create_macro.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "binder/binder.h"
#include "binder/bound_create_macro.h"
#include "common/exception/binder.h"
#include "common/string_format.h"
#include "common/string_utils.h"
#include "parser/create_macro.h"

Expand All @@ -13,8 +14,9 @@ namespace binder {
std::unique_ptr<BoundStatement> Binder::bindCreateMacro(const Statement& statement) {
auto& createMacro = reinterpret_cast<const CreateMacro&>(statement);
auto macroName = createMacro.getMacroName();
StringUtils::toUpper(macroName);
if (catalog.getReadOnlyVersion()->containMacro(macroName)) {
throw BinderException{StringUtils::string_format("Macro {} already exists.", macroName)};
throw BinderException{stringFormat("Macro {} already exists.", macroName)};
}
parser::default_macro_args defaultArgs;
for (auto& defaultArg : createMacro.getDefaultArgs()) {
Expand All @@ -23,7 +25,7 @@ std::unique_ptr<BoundStatement> Binder::bindCreateMacro(const Statement& stateme
auto scalarMacro =
std::make_unique<function::ScalarMacroFunction>(createMacro.getMacroExpression()->copy(),
createMacro.getPositionalArgs(), std::move(defaultArgs));
return std::make_unique<BoundCreateMacro>(macroName, std::move(scalarMacro));
return std::make_unique<BoundCreateMacro>(std::move(macroName), std::move(scalarMacro));
}

} // namespace binder
Expand Down
30 changes: 15 additions & 15 deletions src/binder/bind/bind_ddl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "catalog/rel_table_group_schema.h"
#include "catalog/rel_table_schema.h"
#include "common/exception/binder.h"
#include "common/string_format.h"
#include "common/string_utils.h"
#include "parser/ddl/alter.h"
#include "parser/ddl/create_table.h"
Expand All @@ -26,12 +27,12 @@ std::vector<std::unique_ptr<Property>> Binder::bindProperties(
boundPropertyNameDataTypes.reserve(propertyNameDataTypes.size());
for (auto& propertyNameDataType : propertyNameDataTypes) {
if (boundPropertyNames.contains(propertyNameDataType.first)) {
throw BinderException(StringUtils::string_format(
"Duplicated column name: {}, column name must be unique.",
propertyNameDataType.first));
throw BinderException(
stringFormat("Duplicated column name: {}, column name must be unique.",
propertyNameDataType.first));
} else if (TableSchema::isReservedPropertyName(propertyNameDataType.first)) {
throw BinderException(
StringUtils::string_format("PropertyName: {} is an internal reserved propertyName.",
stringFormat("PropertyName: {} is an internal reserved propertyName.",
propertyNameDataType.first));
}
boundPropertyNameDataTypes.push_back(std::make_unique<Property>(
Expand Down Expand Up @@ -111,10 +112,9 @@ std::unique_ptr<BoundCreateTableInfo> Binder::bindCreateRelTableInfo(const Creat
boundProperty->getDataType()->getLogicalTypeID() == LogicalTypeID::UNION ||
boundProperty->getDataType()->getLogicalTypeID() == LogicalTypeID::STRUCT ||
boundProperty->getDataType()->getLogicalTypeID() == LogicalTypeID::MAP) {
throw BinderException(
StringUtils::string_format("{} property is not supported in rel table.",
LogicalTypeUtils::dataTypeToString(
boundProperty->getDataType()->getLogicalTypeID())));
throw BinderException(stringFormat("{} property is not supported in rel table.",
LogicalTypeUtils::dataTypeToString(
boundProperty->getDataType()->getLogicalTypeID())));
}
}
auto extraInfo = (ExtraCreateRelTableInfo*)info->extraInfo.get();
Expand Down Expand Up @@ -206,9 +206,9 @@ std::unique_ptr<BoundStatement> Binder::bindDropTable(const Statement& statement
for (auto& schema : catalogContent->getRelTableSchemas()) {
auto relTableSchema = reinterpret_cast<RelTableSchema*>(schema);
if (relTableSchema->isSrcOrDstTable(tableID)) {
throw BinderException(StringUtils::string_format(
"Cannot delete node table {} referenced by rel table {}.",
tableSchema->tableName, relTableSchema->tableName));
throw BinderException(
stringFormat("Cannot delete node table {} referenced by rel table {}.",
tableSchema->tableName, relTableSchema->tableName));
}
}
} break;
Expand All @@ -217,9 +217,9 @@ std::unique_ptr<BoundStatement> Binder::bindDropTable(const Statement& statement
auto relTableGroupSchema = reinterpret_cast<RelTableGroupSchema*>(schema);
for (auto& relTableID : relTableGroupSchema->getRelTableIDs()) {
if (relTableID == tableSchema->getTableID()) {
throw BinderException(StringUtils::string_format(
"Cannot delete rel table {} referenced by rel group {}.",
tableSchema->tableName, relTableGroupSchema->tableName));
throw BinderException(
stringFormat("Cannot delete rel table {} referenced by rel group {}.",
tableSchema->tableName, relTableGroupSchema->tableName));
}
}
}
Expand Down Expand Up @@ -287,7 +287,7 @@ static void validatePropertyDDLOnTable(TableSchema* tableSchema, const std::stri
case TableType::REL_GROUP:
case TableType::RDF: {
throw BinderException(
StringUtils::string_format("Cannot {} property on table {} with type {}.", ddlOperation,
stringFormat("Cannot {} property on table {} with type {}.", ddlOperation,
tableSchema->tableName, TableTypeUtils::toString(tableSchema->tableType)));
}
default:
Expand Down
8 changes: 3 additions & 5 deletions src/binder/bind/bind_file_scan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "binder/expression/literal_expression.h"
#include "common/exception/binder.h"
#include "common/exception/copy.h"
#include "common/string_format.h"
#include "common/string_utils.h"

using namespace kuzu::parser;
Expand Down Expand Up @@ -39,15 +40,12 @@ std::vector<std::string> Binder::bindFilePaths(const std::vector<std::string>& f
for (auto& filePath : filePaths) {
auto globbedFilePaths = FileUtils::globFilePath(filePath);
if (globbedFilePaths.empty()) {
throw BinderException{StringUtils::string_format(
"No file found that matches the pattern: {}.", filePath)};
throw BinderException{
stringFormat("No file found that matches the pattern: {}.", filePath)};
}
boundFilePaths.insert(
boundFilePaths.end(), globbedFilePaths.begin(), globbedFilePaths.end());
}
if (boundFilePaths.empty()) {
throw BinderException{StringUtils::string_format("Invalid file path: {}.", filePaths[0])};
}
return boundFilePaths;
}

Expand Down
11 changes: 6 additions & 5 deletions src/binder/bind/bind_graph_pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include "catalog/rel_table_group_schema.h"
#include "catalog/rel_table_schema.h"
#include "common/exception/binder.h"
#include "common/string_utils.h"
#include "common/string_format.h"
#include "function/cast/cast_utils.h"
#include "main/client_context.h"

Expand Down Expand Up @@ -186,9 +186,10 @@ static std::unique_ptr<Expression> createPropertyExpression(const std::string& p
}
for (auto type : propertyDataTypes) {
if (*propertyDataTypes[0] != *type) {
StringUtils::string_format("Expect same data type for property {} but find {} and {}",
propertyName, LogicalTypeUtils::dataTypeToString(*type),
LogicalTypeUtils::dataTypeToString(*propertyDataTypes[0]));
throw BinderException(
stringFormat("Expected the same data type for property {} but found {} and {}.",
propertyName, LogicalTypeUtils::dataTypeToString(*type),
LogicalTypeUtils::dataTypeToString(*propertyDataTypes[0])));
}
}
return make_unique<PropertyExpression>(*propertyDataTypes[0], propertyName, uniqueVariableName,
Expand Down Expand Up @@ -315,7 +316,7 @@ static void bindRecursiveRelProjectionList(const expression_vector& projectionLi
std::vector<std::string>& fieldNames, std::vector<std::unique_ptr<LogicalType>>& fieldTypes) {
for (auto& expression : projectionList) {
if (expression->expressionType != common::PROPERTY) {
throw BinderException(StringUtils::string_format(
throw BinderException(stringFormat(
"Unsupported projection item {} on recursive rel.", expression->toString()));
}
auto property = reinterpret_cast<PropertyExpression*>(expression.get());
Expand Down
12 changes: 6 additions & 6 deletions src/binder/bind/bind_reading_clause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "binder/query/reading_clause/bound_match_clause.h"
#include "binder/query/reading_clause/bound_unwind_clause.h"
#include "common/exception/binder.h"
#include "common/string_format.h"
#include "function/table_functions/bind_input.h"
#include "parser/query/reading_clause/in_query_call_clause.h"
#include "parser/query/reading_clause/load_from.h"
Expand Down Expand Up @@ -189,10 +190,9 @@ void Binder::validateColumnTypes(const std::vector<std::string>& columnNames,
assert(expectedColumnTypes.size() == detectedColumnTypes.size());
for (auto i = 0; i < expectedColumnTypes.size(); ++i) {
if (*expectedColumnTypes[i] != *detectedColumnTypes[i]) {
throw BinderException(
StringUtils::string_format("Column `{}` type mismatch. Expected {} but got {}.",
columnNames[i], LogicalTypeUtils::dataTypeToString(*expectedColumnTypes[i]),
LogicalTypeUtils::dataTypeToString(*detectedColumnTypes[i])));
throw BinderException(stringFormat("Column `{}` type mismatch. Expected {} but got {}.",
columnNames[i], LogicalTypeUtils::dataTypeToString(*expectedColumnTypes[i]),
LogicalTypeUtils::dataTypeToString(*detectedColumnTypes[i])));
}
}
}
Expand All @@ -202,7 +202,7 @@ void Binder::validateNumColumns(uint32_t expectedNumber, uint32_t detectedNumber
return; // Empty CSV. Continue processing.
}
if (expectedNumber != detectedNumber) {
throw BinderException(StringUtils::string_format(
throw BinderException(stringFormat(
"Number of columns mismatch. Expected {} but got {}.", expectedNumber, detectedNumber));
}
}
Expand Down Expand Up @@ -267,7 +267,7 @@ void Binder::sniffFile(const common::ReaderConfig& readerConfig, uint32_t fileId
columnTypes.push_back(columnType->copy());
} break;
default:
throw BinderException(StringUtils::string_format(
throw BinderException(stringFormat(
"Cannot sniff header of file type {}", FileTypeUtils::toString(readerConfig.fileType)));
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/binder/bind/bind_updating_clause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "binder/query/updating_clause/bound_set_clause.h"
#include "catalog/node_table_schema.h"
#include "common/exception/binder.h"
#include "common/string_utils.h"
#include "common/string_format.h"
#include "parser/query/updating_clause/delete_clause.h"
#include "parser/query/updating_clause/insert_clause.h"
#include "parser/query/updating_clause/merge_clause.h"
Expand Down Expand Up @@ -163,7 +163,7 @@ std::unique_ptr<BoundInsertInfo> Binder::bindInsertRelInfo(
}
if (ExpressionUtil::isRecursiveRelVariable(*rel)) {
throw BinderException(
common::StringUtils::string_format("Cannot create recursive rel {}.", rel->toString()));
common::stringFormat("Cannot create recursive rel {}.", rel->toString()));
}
auto relTableID = rel->getSingleTableID();
auto tableSchema = catalog.getReadOnlyVersion()->getTableSchema(relTableID);
Expand Down
4 changes: 2 additions & 2 deletions src/binder/bind_expression/bind_property_expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "binder/expression/rel_expression.h"
#include "binder/expression_binder.h"
#include "common/exception/binder.h"
#include "common/string_utils.h"
#include "common/string_format.h"
#include "parser/expression/parsed_property_expression.h"

using namespace kuzu::common;
Expand Down Expand Up @@ -63,7 +63,7 @@ std::shared_ptr<Expression> ExpressionBinder::bindPropertyExpression(
const ParsedExpression& parsedExpression) {
auto& propertyExpression = (ParsedPropertyExpression&)parsedExpression;
if (propertyExpression.isStar()) {
throw BinderException(StringUtils::string_format(
throw BinderException(stringFormat(
"Cannot bind {} as a single property expression.", parsedExpression.toString()));
}
auto propertyName = propertyExpression.getPropertyName();
Expand Down
10 changes: 4 additions & 6 deletions src/binder/binder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "catalog/rel_table_schema.h"
#include "common/exception/binder.h"
#include "common/exception/not_implemented.h"
#include "common/string_utils.h"
#include "common/string_format.h"

using namespace kuzu::common;
using namespace kuzu::parser;
Expand Down Expand Up @@ -66,8 +66,7 @@ std::shared_ptr<Expression> Binder::bindWhereExpression(const ParsedExpression&
common::table_id_t Binder::bindTableID(const std::string& tableName) const {
auto catalogContent = catalog.getReadOnlyVersion();
if (!catalogContent->containsTable(tableName)) {
throw BinderException(
common::StringUtils::string_format("Table {} does not exist.", tableName));
throw BinderException(common::stringFormat("Table {} does not exist.", tableName));
}
return catalogContent->getTableID(tableName);
}
Expand Down Expand Up @@ -110,9 +109,8 @@ std::unique_ptr<LogicalType> Binder::bindDataType(const std::string& dataType) {
auto numElementsPerPage = storage::PageUtils::getNumElementsInAPage(
storage::StorageUtils::getDataTypeSize(boundType), true /* hasNull */);
if (numElementsPerPage == 0) {
throw BinderException(
StringUtils::string_format("Cannot store a fixed list of size {} in a page.",
storage::StorageUtils::getDataTypeSize(boundType)));
throw BinderException(stringFormat("Cannot store a fixed list of size {} in a page.",
storage::StorageUtils::getDataTypeSize(boundType)));
}
}
return std::make_unique<LogicalType>(boundType);
Expand Down
21 changes: 10 additions & 11 deletions src/binder/expression_binder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ std::shared_ptr<Expression> ExpressionBinder::implicitCastIfNecessary(
if (expression->dataType.getLogicalTypeID() == LogicalTypeID::ANY) {
if (targetTypeID == LogicalTypeID::VAR_LIST) {
// e.g. len($1) we cannot infer the child type for $1.
throw BinderException("Cannot resolve recursive data type for expression " +
expression->toString() + ".");
throw BinderException(stringFormat(
"Cannot resolve recursive data type for expression {}.", expression->toString()));
}
resolveAnyDataType(*expression, LogicalType(targetTypeID));
return expression;
Expand All @@ -118,10 +118,10 @@ std::shared_ptr<Expression> ExpressionBinder::implicitCast(
std::move(bindData), std::move(children), execFunc, nullptr /* selectFunc */,
std::move(uniqueName));
} else {
throw BinderException("Expression " + expression->toString() + " has data type " +
LogicalTypeUtils::dataTypeToString(expression->dataType) +
" but expect " + LogicalTypeUtils::dataTypeToString(targetType) +
". Implicit cast is not supported.");
throw BinderException(stringFormat(
"Expression {} has data type {} but expected {}. Implicit cast is not supported.",
expression->toString(), LogicalTypeUtils::dataTypeToString(expression->dataType),
LogicalTypeUtils::dataTypeToString(targetType)));
}
}

Expand All @@ -139,10 +139,9 @@ void ExpressionBinder::validateExpectedDataType(
auto dataType = expression.dataType;
auto targetsSet = std::unordered_set<LogicalTypeID>{targets.begin(), targets.end()};
if (!targetsSet.contains(dataType.getLogicalTypeID())) {
throw BinderException(expression.toString() + " has data type " +
LogicalTypeUtils::dataTypeToString(dataType.getLogicalTypeID()) +
". " + LogicalTypeUtils::dataTypesToString(targets) +
" was expected.");
throw BinderException(stringFormat("{} has data type {} but {} was expected.",
expression.toString(), LogicalTypeUtils::dataTypeToString(dataType.getLogicalTypeID()),
LogicalTypeUtils::dataTypesToString(targets)));
}
}

Expand All @@ -152,7 +151,7 @@ void ExpressionBinder::validateAggregationExpressionIsNotNested(const Expression
}
if (ExpressionVisitor::hasAggregate(*expression.getChild(0))) {
throw BinderException(
"Expression " + expression.toString() + " contains nested aggregation.");
stringFormat("Expression {} contains nested aggregation.", expression.toString()));
}
}

Expand Down
1 change: 1 addition & 0 deletions src/c_api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ add_library(kuzu_c_api
connection.cpp
database.cpp
data_type.cpp
helpers.cpp
flat_tuple.cpp
prepared_statement.cpp
query_result.cpp
Expand Down
1 change: 1 addition & 0 deletions src/c_api/connection.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "binder/bound_statement_result.h"
#include "c_api/helpers.h"
#include "c_api/kuzu.h"
#include "common/exception/exception.h"
#include "main/kuzu.h"
Expand Down
6 changes: 2 additions & 4 deletions src/c_api/flat_tuple.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "processor/result/flat_tuple.h"

#include "c_api/helpers.h"
#include "c_api/kuzu.h"
#include "common/exception/exception.h"

Expand Down Expand Up @@ -35,8 +36,5 @@ kuzu_value* kuzu_flat_tuple_get_value(kuzu_flat_tuple* flat_tuple, uint64_t inde

char* kuzu_flat_tuple_to_string(kuzu_flat_tuple* flat_tuple) {
auto flat_tuple_shared_ptr = static_cast<std::shared_ptr<FlatTuple>*>(flat_tuple->_flat_tuple);
auto string = (*flat_tuple_shared_ptr)->toString();
char* string_c = (char*)malloc(string.size() + 1);
strcpy(string_c, string.c_str());
return string_c;
return convertToOwnedCString((*flat_tuple_shared_ptr)->toString());
}
11 changes: 11 additions & 0 deletions src/c_api/helpers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "c_api/helpers.h"

#include <cstring>

char* convertToOwnedCString(const std::string& str) {
size_t src_len = str.size();
auto* c_str = (char*)malloc(sizeof(char) * (src_len + 1));
memcpy(c_str, str.c_str(), src_len);
c_str[src_len] = '\0';
return c_str;
}
Loading