Skip to content

Commit

Permalink
Merge pull request #2319 from langston-barrett/lb/warns
Browse files Browse the repository at this point in the history
Configurable warnings
  • Loading branch information
b-scholz authored Oct 27, 2022
2 parents d4de39b + 9f37121 commit 1fc233d
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 16 deletions.
3 changes: 2 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ set(SOUFFLE_SOURCES
ram/transform/Transformer.cpp
ram/transform/TupleId.cpp
ram/utility/NodeMapper.cpp
reports/ErrorReport.cpp
reports/DebugReport.cpp
synthesiser/Synthesiser.cpp
synthesiser/Relation.cpp
Expand Down Expand Up @@ -319,7 +320,7 @@ target_link_libraries(souffle libsouffle)
install(TARGETS souffle DESTINATION bin)

if (EMSCRIPTEN)
target_link_libraries(souffle -sMODULARIZE=1
target_link_libraries(souffle -sMODULARIZE=1
-s'EXPORTED_RUNTIME_METHODS=["FS"]' -sEXPORT_NAME="SOUFFLE")
endif()

Expand Down
12 changes: 8 additions & 4 deletions src/ast/transform/SemanticChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,8 @@ void SemanticCheckerImpl::checkClause(const Clause& clause) {
if (varName[0] == '_') {
assert(varName.size() > 1 && "named variable should not be a single underscore");
if (numAppearances > 1) {
report.addWarning("Variable " + varName + " marked as singleton but occurs more than once",
report.addWarning(WarnType::VarAppearsOnce,
"Variable " + varName + " marked as singleton but occurs more than once",
varLocation);
}
}
Expand Down Expand Up @@ -549,7 +550,8 @@ void SemanticCheckerImpl::checkComplexRule(const std::set<const Clause*>& multiR
const auto& varName = cur.first;
const auto& varLocation = var_pos[varName]->getSrcLoc();
if (varName[0] != '_' && numAppearances == 1) {
report.addWarning("Variable " + varName + " only occurs once", varLocation);
report.addWarning(
WarnType::VarAppearsOnce, "Variable " + varName + " only occurs once", varLocation);
}
}
}
Expand Down Expand Up @@ -644,7 +646,8 @@ void SemanticCheckerImpl::checkRelation(const Relation& relation) {
return sClause.getHead()->getQualifiedName() == relation.getQualifiedName();
});
if (relation.getRepresentation() == RelationRepresentation::BTREE_DELETE && !hasSubsumptiveRule) {
report.addWarning("No subsumptive rule for relation " + toString(relation.getQualifiedName()),
report.addWarning(WarnType::NoSubsumptiveRule,
"No subsumptive rule for relation " + toString(relation.getQualifiedName()),
relation.getSrcLoc());
} else if (relation.getRepresentation() != RelationRepresentation::BTREE_DELETE && hasSubsumptiveRule) {
report.addError("Relation \"" + toString(relation.getQualifiedName()) +
Expand All @@ -667,7 +670,8 @@ void SemanticCheckerImpl::checkRelation(const Relation& relation) {
// check whether this relation is empty
if (program.getClauses(relation).empty() && !ioTypes.isInput(&relation) &&
!relation.hasQualifier(RelationQualifier::SUPPRESSED)) {
report.addWarning("No rules/facts defined for relation " + toString(relation.getQualifiedName()),
report.addWarning(WarnType::NoRulesNorFacts,
"No rules/facts defined for relation " + toString(relation.getQualifiedName()),
relation.getSrcLoc());
}
}
Expand Down
39 changes: 38 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,38 @@ class MCPPPreprocInput : public PreprocInput {
}
};

static WarnSet process_warn_opts(void) {
WarnSet warns;
if (!Global::config().has("no-warn")) {
if (Global::config().has("warn")) {
for (auto&& option : Global::config().getMany("warn")) {
if (option == "all") {
warns.set();
} else {
auto valid = warns.setStr(option);
if (!valid) {
throw std::runtime_error("no such warning " + std::string(option));
}
}
}
}
if (Global::config().has("wno")) {
for (auto&& option : Global::config().getMany("wno")) {
if (option == "none") { // default
} else if (option == "all") {
warns.reset();
} else {
auto valid = warns.resetStr(option);
if (!valid) {
throw std::runtime_error("no such warning " + std::string(option));
}
}
}
}
}
return warns;
}

int main(int argc, char** argv) {
/* Time taking for overall runtime */
auto souffle_start = std::chrono::high_resolution_clock::now();
Expand Down Expand Up @@ -423,6 +455,10 @@ int main(int argc, char** argv) {
{"library-dir", 'L', "DIR", "", true, "Specify directory for library files."},
{"libraries", 'l', "FILE", "", true, "Specify libraries."},
{"no-warn", 'w', "", "", false, "Disable warnings."},
{"warn", 'W', "WARN", "all", true, "Enable a warning."},
{"wno", '\xb', "WARN", "none", true, "Disable a specific warning."},
// TODO(lb):
// {"Werror", '\xc', "WARN", "none", false, "Turn a warning into an error."},
{"magic-transform", 'm', "RELATIONS", "", false,
"Enable magic set transformation changes on the given relations, use '*' "
"for all."},
Expand Down Expand Up @@ -619,7 +655,8 @@ int main(int argc, char** argv) {
// ------- parse program -------------

// parse file
ErrorReport errReport(Global::config().has("no-warn"));
ErrorReport errReport(process_warn_opts());

DebugReport debugReport;
Own<ast::TranslationUnit> astTranslationUnit = ParserDriver::parseTranslationUnit(
InputPath.string(), Input->getInputStream(), errReport, debugReport);
Expand Down
11 changes: 6 additions & 5 deletions src/parser/ParserDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,14 +209,15 @@ void ParserDriver::addIoFromDeprecatedTag(ast::Relation& rel) {
std::set<RelationTag> ParserDriver::addDeprecatedTag(
RelationTag tag, SrcLocation tagLoc, std::set<RelationTag> tags) {
if (!Global::config().has("legacy")) {
warning(tagLoc, tfm::format("Deprecated %s qualifier was used", tag));
warning(WarnType::DeprecatedQualifier, tagLoc, tfm::format("Deprecated %s qualifier was used", tag));
}
return addTag(tag, std::move(tagLoc), std::move(tags));
}

Own<ast::Counter> ParserDriver::addDeprecatedCounter(SrcLocation tagLoc) {
if (!Global::config().has("legacy")) {
warning(tagLoc, "Deprecated $ symbol was used. Use functor 'autoinc()' instead.");
warning(WarnType::DollarSign, tagLoc,
"Deprecated $ symbol was used. Use functor 'autoinc()' instead.");
}
return mk<ast::Counter>();
}
Expand Down Expand Up @@ -244,13 +245,13 @@ std::set<RelationTag> ParserDriver::addTag(RelationTag tag, std::vector<Relation
Own<ast::SubsetType> ParserDriver::mkDeprecatedSubType(
ast::QualifiedName name, ast::QualifiedName baseTypeName, SrcLocation loc) {
if (!Global::config().has("legacy")) {
warning(loc, "Deprecated type declaration used");
warning(WarnType::DeprecatedTypeDecl, loc, "Deprecated type declaration used");
}
return mk<ast::SubsetType>(std::move(name), std::move(baseTypeName), std::move(loc));
}

void ParserDriver::warning(const SrcLocation& loc, const std::string& msg) {
translationUnit->getErrorReport().addWarning(msg, loc);
void ParserDriver::warning(const WarnType type, const SrcLocation& loc, const std::string& msg) {
translationUnit->getErrorReport().addWarning(type, msg, loc);
}
void ParserDriver::error(const SrcLocation& loc, const std::string& msg) {
translationUnit->getErrorReport().addError(msg, loc);
Expand Down
2 changes: 1 addition & 1 deletion src/parser/ParserDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class ParserDriver {
static Own<ast::TranslationUnit> parseTranslationUnit(
const std::string& code, ErrorReport& errorReport, DebugReport& debugReport);

void warning(const SrcLocation& loc, const std::string& msg);
void warning(const WarnType warn, const SrcLocation& loc, const std::string& msg);
void error(const SrcLocation& loc, const std::string& msg);
void error(const std::string& msg);

Expand Down
76 changes: 76 additions & 0 deletions src/reports/ErrorReport.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Souffle - A Datalog Compiler
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved
* Licensed under the Universal Permissive License v 1.0 as shown at:
* - https://opensource.org/licenses/UPL
* - <souffle root>/licenses/SOUFFLE-UPL.txt
*/

/************************************************************************
*
* @file reports/ErrorReport.h
*
* Defines a class for error reporting.
*
***********************************************************************/

#include "reports/ErrorReport.h"

namespace souffle {

std::optional<WarnType> WarnSet::warnTypeFromString(const std::string& s) {
if (s == "deprecated-type-decl") {
return std::optional<WarnType>(WarnType::DeprecatedTypeDecl);
} else if (s == "deprecated-qualifier") {
return std::optional<WarnType>(WarnType::DeprecatedQualifier);
} else if (s == "dollar-sign") {
return std::optional<WarnType>(WarnType::DollarSign);
} else if (s == "no-rules-nor-facts") {
return std::optional<WarnType>(WarnType::NoRulesNorFacts);
} else if (s == "no-subsumptive-rule") {
return std::optional<WarnType>(WarnType::NoSubsumptiveRule);
} else if (s == "var-appears-once") {
return std::optional<WarnType>(WarnType::VarAppearsOnce);
}
return std::optional<WarnType>(std::nullopt);
}

bool WarnSet::test(const WarnType warn) {
return warns.test(static_cast<std::size_t>(warn));
}

void WarnSet::set(const WarnType warn) {
warns.set(static_cast<std::size_t>(warn));
}

void WarnSet::set() {
warns.set();
}

void WarnSet::reset(const WarnType warn) {
warns.reset(static_cast<std::size_t>(warn));
}

void WarnSet::reset() {
warns.reset();
}

bool WarnSet::setStr(const std::string& str) {
const auto warn = warnTypeFromString(str);
if (warn.has_value()) {
this->set(warn.value());
return true;
}
return false;
}

bool WarnSet::resetStr(const std::string& str) {
const auto warn = warnTypeFromString(str);
if (warn.has_value()) {
this->reset(warn.value());
return true;
}
return false;
}

}; // namespace souffle
62 changes: 58 additions & 4 deletions src/reports/ErrorReport.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@

#include "parser/SrcLocation.h"
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cstdlib>
#include <iostream>
#include <optional>
#include <set>
#include <string>
#include <utility>
Expand Down Expand Up @@ -143,9 +145,61 @@ class Diagnostic {
std::vector<DiagnosticMessage> additionalMessages;
};

enum class WarnType : std::size_t {
DeprecatedTypeDecl,
DeprecatedQualifier,
DollarSign,
NoRulesNorFacts,
NoSubsumptiveRule,
// This last element is used as the size parameter to std::bitset in the
// definition of WarnSet. If the last element changes, the definition of
// WarnSet must be updated accordingly.
VarAppearsOnce,
};

class WarnSet {
public:
WarnSet() : warns(std::bitset<(std::size_t)WarnType::VarAppearsOnce + 1>()) {
this->set(); // default to enabling all warnings
}

WarnSet(const WarnSet& other) = default;

bool test(const WarnType warn);

// Enable all warnings
void set();

// Enable one warning
void set(const WarnType warn);

// Disable all warnings
void reset(const WarnType warn);

// Disable one warning
void reset();

// Enable one warning
//
// Returns whether or not the string was valid
bool setStr(const std::string& str);

// Disable one warning
//
// Returns whether or not the string was valid
bool resetStr(const std::string& str);

private:
std::bitset<(std::size_t)WarnType::VarAppearsOnce + 1> warns;

std::optional<WarnType> warnTypeFromString(const std::string& s);
};

class ErrorReport {
public:
ErrorReport(bool nowarn = false) : nowarn(nowarn) {}
ErrorReport() : warns(WarnSet()) {}

ErrorReport(WarnSet warns) : warns(warns) {}

ErrorReport(const ErrorReport& other) = default;

Expand All @@ -170,8 +224,8 @@ class ErrorReport {
}

/** Adds a warning with the given message and location */
void addWarning(const std::string& message, SrcLocation location) {
if (!nowarn) {
void addWarning(const WarnType type, const std::string& message, SrcLocation location) {
if (warns.test(type)) {
diagnostics.insert(
Diagnostic(Diagnostic::Type::WARNING, DiagnosticMessage(message, std::move(location))));
}
Expand Down Expand Up @@ -203,7 +257,7 @@ class ErrorReport {

private:
std::set<Diagnostic> diagnostics;
bool nowarn;
WarnSet warns;
};

} // end of namespace souffle

0 comments on commit 1fc233d

Please sign in to comment.