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

[TESTING] Switch compilation from C++17 to C++20 #4874

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion .bazelrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
build --action_env=BAZEL_CXXOPTS="-std=c++17"
build --action_env=BAZEL_CXXOPTS="-std=c++20"
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ IncludeBlocks: Regroup
# Force pointers to the type for C++.
DerivePointerAlignment: false
PointerAlignment: Right
Standard: c++17
Standard: c++20
IncludeCategories:
# Matches common headers first and sorts them before project includes
- Regex: '^<.+/.*\.h>'
Expand Down
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ endif()

project (P4C)

# set (CMAKE_CXX_EXTENSIONS OFF) # prefer using -std=c++17 rather than -std=gnu++17
set (CMAKE_CXX_STANDARD 17)
# set (CMAKE_CXX_EXTENSIONS OFF) # prefer using -std=c++20 rather than -std=gnu++20
set (CMAKE_CXX_STANDARD 20)
set (CMAKE_CXX_STANDARD_REQUIRED ON)

set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
Expand Down
11 changes: 5 additions & 6 deletions backends/p4tools/common/lib/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,17 @@
#include <string>
#include <utility>

#include <boost/format.hpp>

#include "lib/boost_format_compat.h"
#include "lib/log.h"

namespace P4::P4Tools {

/// Helper function for @printFeature
inline std::string logHelper(boost::format &f) { return f.str(); }
inline BoostFormatCompat &logHelper(BoostFormatCompat &f) { return f; }

/// Helper function for @printFeature
template <class T, class... Args>
std::string logHelper(boost::format &f, T &&t, Args &&...args) {
BoostFormatCompat &logHelper(BoostFormatCompat &f, T &&t, Args &&...args) {
return logHelper(f % std::forward<T>(t), std::forward<Args>(args)...);
}

Expand All @@ -32,8 +31,8 @@ void printFeature(const std::string &label, int level, const std::string &fmt,
return;
}

boost::format f(fmt);
LOG_FEATURE(label.c_str(), level, logHelper(f, std::forward<Arguments>(args)...));
BoostFormatCompat f(fmt.c_str());
LOG_FEATURE(label.c_str(), level, logHelper(f, std::forward<Arguments>(args)...).str());
}

/// Helper functions that prints strings associated with basic tool information.
Expand Down
2 changes: 1 addition & 1 deletion bazel/example/.bazelrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
build --action_env=BAZEL_CXXOPTS="-std=c++17"
build --action_env=BAZEL_CXXOPTS="-std=c++20"
2 changes: 1 addition & 1 deletion docs/C++.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
C++ (following the C++ 11 standard) is the implementation language for
C++ (following the C++ 20 standard) is the implementation language for
the compiler. This file contains notes on how we use C++ and conventions
we use for things that C++ does not handle well.

Expand Down
6 changes: 3 additions & 3 deletions frontends/p4/typeChecking/typeCheckTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,13 +331,13 @@ static bool checkEnumValueInitializer(const IR::Type_Bits *type, const IR::Expre
std::string extraMsg;
if (!type->isSigned && constant->value < low) {
extraMsg =
str(boost::format(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one only does string interpolation. Maybe get rid of boost::format entirely here to reduce the footprint. Same below.

str(BoostFormatCompat(
"the value %1% is negative, but the underlying type %2% is unsigned") %
constant->value % type->toString());
} else {
extraMsg =
str(boost::format("the value %1% requires %2% bits but the underlying "
"%3% type %4% only contains %5% bits") %
str(BoostFormatCompat("the value %1% requires %2% bits but the underlying "
"%3% type %4% only contains %5% bits") %
constant->value % required % (type->isSigned ? "signed" : "unsigned") %
type->toString() % type->size);
}
Expand Down
2 changes: 1 addition & 1 deletion frontends/p4/typeChecking/typeConstraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ std::string TypeConstraint::localError(Explain *explainer) const {
if (errFormat.isNullOrEmpty()) return "";

std::string message, explanation;
boost::format fmt = boost::format(errFormat);
BoostFormatCompat fmt(errFormat);
switch (errArguments.size()) {
case 0:
message = boost::str(fmt);
Expand Down
2 changes: 1 addition & 1 deletion frontends/p4/typeChecking/typeConstraints.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class TypeConstraint : public IHasDbPrint, public ICastable {
/// composed in reverse order, from bottom to top. The top of the stack
/// has no 'derivedFrom' field, and it contains the actual source
/// position where the analysis started.
boost::format fmt(format);
BoostFormatCompat fmt(format);
return reportErrorImpl(subst,
" ---- Actual error:\n" +
::P4::error_helper(fmt, std::forward<Args>(args)...).toString());
Expand Down
5 changes: 2 additions & 3 deletions frontends/parsers/parserDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
#include <sstream>
#include <string_view>

#include <boost/format.hpp>

#include "frontends/common/constantFolding.h"
#include "frontends/common/options.h"
#include "frontends/parsers/p4/p4AnnotationLexer.hpp"
#include "frontends/parsers/p4/p4lexer.hpp"
#include "frontends/parsers/p4/p4parser.hpp"
#include "frontends/parsers/v1/v1lexer.hpp"
#include "frontends/parsers/v1/v1parser.hpp"
#include "lib/boost_format_compat.h"
#include "lib/error.h"

#ifdef HAVE_LIBBOOST_IOSTREAMS
Expand Down Expand Up @@ -108,7 +107,7 @@ void AbstractParserDriver::onParseError(const Util::SourceInfo &location,
auto &context = BaseCompileContext::get();
if (message == unexpectedIdentifierError) {
context.errorReporter().parser_error(
location, boost::format("%s \"%s\"") % unexpectedIdentifierError % lastIdentifier);
location, BoostFormatCompat("%s \"%s\"") % unexpectedIdentifierError % lastIdentifier);
} else {
context.errorReporter().parser_error(location, message);
}
Expand Down
53 changes: 53 additions & 0 deletions lib/boost_format_compat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#ifndef LIB_BOOST_FORMAT_COMPAT_H_
#define LIB_BOOST_FORMAT_COMPAT_H_

#include <boost/format.hpp>

namespace P4 {

/// Allocator wrapper that adds the overload removed in C++20 for the sake of Boost.
template <typename T>
struct BoostCompatAllocator : std::allocator<T> {
/// Inherit constructors.
using std::allocator<T>::allocator;

BoostCompatAllocator() = default;
/// Explictly make it possible to construct our allocator from std::allocator.
/// Some parts of libstdc++ 9 require that for some reason.
BoostCompatAllocator(const std::allocator<T> &other)
: std::allocator<T>(other) {} // NOLINT(runtime/explicit)
BoostCompatAllocator(std::allocator<T> &&other)
: std::allocator<T>(std::move(other)) {} // NOLINT(runtime/explicit)

/// This one was removed in C++20, but boost::format < 1.74 needs it.
T *allocate(typename std::allocator<T>::size_type n, const void *) { return allocate(n); }

/// Explicitly wrap the other overload (instead of using using std::allocator<T>::allocate.
/// The latter does not work with GCC 9.
T *allocate(typename std::allocator<T>::size_type n) { return std::allocator<T>::allocate(n); }
};

/// Boost < 1.74 is not compatible with C++20 as it expect deprecated
/// allocator::allocate(size_type, void*) to exist. To work around that, we use a simple wrapper
/// over std::allocator that adds this overload back. All uses of boost::format in P4C should use
// this type instead.
using BoostFormatCompat =
boost::basic_format<char, std::char_traits<char>, BoostCompatAllocator<char>>;

} // namespace P4

#endif // LIB_BOOST_FORMAT_COMPAT_H_
19 changes: 9 additions & 10 deletions lib/bug_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ limitations under the License.
#include <string_view>
#include <utility>

#include <boost/format.hpp>

#include "absl/strings/str_cat.h"
#include "boost_format_compat.h"
#include "cstring.h"
#include "source_file.h"
#include "stringify.h"
Expand Down Expand Up @@ -60,27 +59,27 @@ std::pair<std::string_view, std::string> maybeAddSourceInfo(const T &t, std::str
return {"", ""};
}

static inline std::string bug_helper(boost::format &f, std::string_view position,
static inline std::string bug_helper(BoostFormatCompat &f, std::string_view position,
std::string_view tail) {
return absl::StrCat(position, position.empty() ? "" : ": ", boost::str(f), "\n", tail);
}

template <typename T, class... Args>
auto bug_helper(boost::format &f, std::string_view position, std::string_view tail, const T *t,
auto bug_helper(BoostFormatCompat &f, std::string_view position, std::string_view tail, const T *t,
Args &&...args);

template <typename T, class... Args>
auto bug_helper(boost::format &f, std::string_view position, std::string_view tail, const T &t,
auto bug_helper(BoostFormatCompat &f, std::string_view position, std::string_view tail, const T &t,
Args &&...args) -> std::enable_if_t<!std::is_pointer_v<T>, std::string>;

template <class... Args>
std::string bug_helper(boost::format &f, std::string_view position, std::string_view tail,
std::string bug_helper(BoostFormatCompat &f, std::string_view position, std::string_view tail,
const char *t, Args &&...args) {
return bug_helper(f % t, position, tail, std::forward<Args>(args)...);
}

template <class... Args>
std::string bug_helper(boost::format &f, std::string_view position, std::string_view tail,
std::string bug_helper(BoostFormatCompat &f, std::string_view position, std::string_view tail,
const Util::SourceInfo &info, Args &&...args) {
auto [outPos, outTail] = detail::getPositionTail(info, position, tail);
return bug_helper(f % "", outPos, outTail, std::forward<Args>(args)...);
Expand All @@ -105,7 +104,7 @@ std::ostream &operator<<(std::ostream &os, const DbprintDispatchPtr<T> &dispatch
}

template <typename T, class... Args>
auto bug_helper(boost::format &f, std::string_view position, std::string_view tail, const T *t,
auto bug_helper(BoostFormatCompat &f, std::string_view position, std::string_view tail, const T *t,
Args &&...args) {
if (t == nullptr) return bug_helper(f, position, tail, std::forward<Args>(args)...);

Expand All @@ -132,7 +131,7 @@ std::ostream &operator<<(std::ostream &os, const DbprintDispatchRef<T> &dispatch
}

template <typename T, class... Args>
auto bug_helper(boost::format &f, std::string_view position, std::string_view tail, const T &t,
auto bug_helper(BoostFormatCompat &f, std::string_view position, std::string_view tail, const T &t,
Args &&...args) -> std::enable_if_t<!std::is_pointer_v<T>, std::string> {
auto [outPos, outTail] = maybeAddSourceInfo(t, position, tail);
return bug_helper(f % DbprintDispatchRef<T>{t}, outPos, outTail, std::forward<Args>(args)...);
Expand All @@ -141,7 +140,7 @@ auto bug_helper(boost::format &f, std::string_view position, std::string_view ta

// Most direct invocations of bug_helper usually only reduce arguments
template <class... Args>
std::string bug_helper(boost::format &f, std::string_view position, std::string_view tail,
std::string bug_helper(BoostFormatCompat &f, std::string_view position, std::string_view tail,
Args &&...args) {
return detail::bug_helper(f, position, tail, std::forward<Args>(args)...);
}
Expand Down
31 changes: 15 additions & 16 deletions lib/error_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ limitations under the License.

#include <type_traits>

#include <boost/format.hpp>

#include "lib/boost_format_compat.h"
#include "lib/error_message.h"
#include "lib/source_file.h"
#include "lib/stringify.h"
Expand All @@ -29,34 +28,34 @@ namespace priv {

// All these methods return std::string because this is the native format of boost::format
// Position is printed at the beginning.
static inline ErrorMessage error_helper(boost::format &f, ErrorMessage out) {
static inline ErrorMessage error_helper(BoostFormatCompat &f, ErrorMessage out) {
out.message = boost::str(f);
return out;
}

template <class... Args>
auto error_helper(boost::format &f, ErrorMessage out, const char *t, Args &&...args) {
auto error_helper(BoostFormatCompat &f, ErrorMessage out, const char *t, Args &&...args) {
return error_helper(f % t, out, std::forward<Args>(args)...);
}

template <typename T, class... Args>
auto error_helper(boost::format &f, ErrorMessage out, const T &t,
Args &&...args) -> std::enable_if_t<Util::has_toString_v<T>, ErrorMessage>;
auto error_helper(BoostFormatCompat &f, ErrorMessage out, const T &t, Args &&...args)
-> std::enable_if_t<Util::has_toString_v<T>, ErrorMessage>;

template <typename T, class... Args>
auto error_helper(boost::format &f, ErrorMessage out, const T &t, Args &&...args)
auto error_helper(BoostFormatCompat &f, ErrorMessage out, const T &t, Args &&...args)
-> std::enable_if_t<!Util::has_toString_v<T> && !std::is_pointer_v<T>, ErrorMessage>;

template <typename T, class... Args>
auto error_helper(boost::format &f, ErrorMessage out, const T *t, Args &&...args) {
auto error_helper(BoostFormatCompat &f, ErrorMessage out, const T *t, Args &&...args) {
// Contrary to bug_helper we do not want to show raw pointers to users in
// ordinary error messages. Therefore we explicitly delegate to
// reference-arg implementation here.
return error_helper(f, out, *t, std::forward<Args>(args)...);
}

template <class... Args>
ErrorMessage error_helper(boost::format &f, ErrorMessage out, const Util::SourceInfo &info,
ErrorMessage error_helper(BoostFormatCompat &f, ErrorMessage out, const Util::SourceInfo &info,
Args &&...args) {
if (info.isValid()) out.locations.push_back(info);
return error_helper(f % "", std::move(out), std::forward<Args>(args)...);
Expand All @@ -71,15 +70,15 @@ void maybeAddSourceInfo(ErrorMessage &out, const T &t) {
}

template <typename T, class... Args>
auto error_helper(boost::format &f, ErrorMessage out, const T &t, Args &&...args)
auto error_helper(BoostFormatCompat &f, ErrorMessage out, const T &t, Args &&...args)
-> std::enable_if_t<!Util::has_toString_v<T> && !std::is_pointer_v<T>, ErrorMessage> {
maybeAddSourceInfo(out, t);
return error_helper(f % t, std::move(out), std::forward<Args>(args)...);
}

template <typename T, class... Args>
auto error_helper(boost::format &f, ErrorMessage out, const T &t,
Args &&...args) -> std::enable_if_t<Util::has_toString_v<T>, ErrorMessage> {
auto error_helper(BoostFormatCompat &f, ErrorMessage out, const T &t, Args &&...args)
-> std::enable_if_t<Util::has_toString_v<T>, ErrorMessage> {
maybeAddSourceInfo(out, t);
return error_helper(f % t.toString(), std::move(out), std::forward<Args>(args)...);
}
Expand All @@ -88,21 +87,21 @@ auto error_helper(boost::format &f, ErrorMessage out, const T &t,

// Most direct invocations of error_helper usually only reduce arguments
template <class... Args>
ErrorMessage error_helper(boost::format &f, Args &&...args) {
ErrorMessage error_helper(BoostFormatCompat &f, Args &&...args) {
ErrorMessage msg;
return priv::error_helper(f, msg, std::forward<Args>(args)...);
}

// Invoked from ErrorReporter
template <class... Args>
ErrorMessage error_helper(boost::format &f, ErrorMessage msg, Args &&...args) {
ErrorMessage error_helper(BoostFormatCompat &f, ErrorMessage msg, Args &&...args) {
return priv::error_helper(f, std::move(msg), std::forward<Args>(args)...);
}

// This overload exists for backwards compatibility
template <class... Args>
ErrorMessage error_helper(boost::format &f, const std::string &prefix, const Util::SourceInfo &info,
const std::string &suffix, Args &&...args) {
ErrorMessage error_helper(BoostFormatCompat &f, const std::string &prefix,
const Util::SourceInfo &info, const std::string &suffix, Args &&...args) {
return priv::error_helper(f, ErrorMessage(prefix, info, suffix), std::forward<Args>(args)...);
}

Expand Down
9 changes: 4 additions & 5 deletions lib/error_reporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ limitations under the License.
#include <type_traits>
#include <unordered_map>

#include <boost/format.hpp>

#include "absl/strings/str_format.h"
#include "boost_format_compat.h"
#include "bug_helper.h"
#include "error_catalog.h"
#include "error_helper.h"
Expand Down Expand Up @@ -96,15 +95,15 @@ class ErrorReporter {
// error message for a bug
template <typename... Args>
std::string bug_message(const char *format, Args &&...args) {
boost::format fmt(format);
BoostFormatCompat fmt(format);
// FIXME: This will implicitly take location of the first argument having
// SourceInfo. Not sure if this always desireable or not.
return ::P4::bug_helper(fmt, "", "", std::forward<Args>(args)...);
}

template <typename... Args>
std::string format_message(const char *format, Args &&...args) {
boost::format fmt(format);
BoostFormatCompat fmt(format);
return ::P4::error_helper(fmt, std::forward<Args>(args)...).toString();
}

Expand Down Expand Up @@ -157,7 +156,7 @@ class ErrorReporter {
msgType = ErrorMessage::MessageType::Error;
}

boost::format fmt(format);
BoostFormatCompat fmt(format);
ErrorMessage msg(msgType, diagnosticName ? diagnosticName : "", suffix);
msg = ::P4::error_helper(fmt, msg, std::forward<Args>(args)...);
emit_message(msg);
Expand Down
2 changes: 1 addition & 1 deletion lib/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class P4CExceptionBase : public std::exception {
template <typename... Args>
explicit P4CExceptionBase(const char *format, Args &&...args) {
traceCreation();
boost::format fmt(format);
BoostFormatCompat fmt(format);
// FIXME: This will implicitly take location of the first argument having
// SourceInfo. Not sure if this always desireable or not.
message = ::P4::bug_helper(fmt, "", "", std::forward<Args>(args)...);
Expand Down
Loading