Follow practices suggested by "Effective C++"

The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:

* A class with virtual functions can no longer publicly inherit base
  classed without a vtable. The inherited object may either be moved
  to a member variable, or inherited privately. The latter would be
  used for classes that inherit 'List::Element' or 'Avl_node'. In order
  to enable the 'List' and 'Avl_tree' to access the meta data, the
  'List' must become a friend.

* Instead of adding a virtual destructor to abstract base classes,
  we inherit the new 'Interface' class, which contains a virtual
  destructor. This way, single-line abstract base classes can stay
  as compact as they are now. The 'Interface' utility resides in
  base/include/util/interface.h.

* With the new warnings enabled, all member variables must be explicitly
  initialized. Basic types may be initialized with '='. All other types
  are initialized with braces '{ ... }' or as class initializers. If
  basic types and non-basic types appear in a row, it is nice to only
  use the brace syntax (also for basic types) and align the braces.

* If a class contains pointers as members, it must now also provide a
  copy constructor and assignment operator. In the most cases, one
  would make them private, effectively disallowing the objects to be
  copied. Unfortunately, this warning cannot be fixed be inheriting
  our existing 'Noncopyable' class (the compiler fails to detect that
  the inheriting class cannot be copied and still gives the error).
  For now, we have to manually add declarations for both the copy
  constructor and assignment operator as private class members. Those
  declarations should be prepended with a comment like this:

        /*
         * Noncopyable
         */
        Thread(Thread const &);
        Thread &operator = (Thread const &);

  In the future, we should revisit these places and try to replace
  the pointers with references. In the presence of at least one
  reference member, the compiler would no longer implicitly generate
  a copy constructor. So we could remove the manual declaration.

Issue #465
This commit is contained in:
Norman Feske
2017-12-21 15:42:15 +01:00
committed by Christian Helmuth
parent 2a33d9aa76
commit eba9c15746
763 changed files with 4936 additions and 3288 deletions

View File

@ -196,7 +196,7 @@ void Child::Initial_thread::start(addr_t ip)
Child::Process::Process(Dataspace_capability elf_ds,
Dataspace_capability ldso_ds,
Pd_session_capability pd_cap,
Pd_session_capability,
Pd_session &pd,
Ram_session &ram,
Initial_thread_base &initial_thread,

View File

@ -49,7 +49,7 @@ namespace {
/**
* Lock for serializing 'session' and 'close'
*/
Genode::Lock _lock;
Genode::Lock _lock { };
/**
* Utility to used block for single signal
@ -57,8 +57,8 @@ namespace {
struct Blockade
{
Parent &_parent;
Genode::Signal_receiver _sig_rec;
Genode::Signal_context _sig_ctx;
Genode::Signal_receiver _sig_rec { };
Genode::Signal_context _sig_ctx { };
Blockade(Parent &parent) : _parent(parent)
{
@ -68,7 +68,7 @@ namespace {
void block() { _sig_rec.wait_for_signal(); }
};
Constructible<Blockade> _session_blockade;
Constructible<Blockade> _session_blockade { };
Env(Genode::Entrypoint &ep) : _ep(ep) { env_ptr = this; }

View File

@ -264,7 +264,7 @@ void Genode::Entrypoint::dissolve(Signal_dispatcher_base &dispatcher)
namespace {
struct Constructor
struct Constructor : Interface
{
GENODE_RPC(Rpc_construct, void, construct);
GENODE_RPC_INTERFACE(Rpc_construct);

View File

@ -36,11 +36,11 @@ class Log_console : public Console
{ }
};
Log _log;
Log _log { };
char _buf[_BUF_SIZE];
unsigned _num_chars;
Lock _lock;
char _buf[_BUF_SIZE] { };
unsigned _num_chars = 0;
Lock _lock { };
void _flush()
{
@ -71,10 +71,7 @@ class Log_console : public Console
/**
* Constructor
*/
Log_console()
:
_num_chars(0)
{ }
Log_console() { }
/**
* Console interface

View File

@ -51,8 +51,8 @@ namespace {
enum { MAX = 32 };
Lock mutable _lock;
Service _services[MAX];
Lock mutable _lock { };
Service _services[MAX] { };
unsigned _cnt = 0;
public:
@ -114,7 +114,7 @@ namespace {
Env &_env;
Id_space<Parent::Server> _id_space;
Id_space<Parent::Server> _id_space { };
Entrypoint _ep { _env, 2*1024*sizeof(long), "root" };
@ -130,7 +130,7 @@ namespace {
void _handle_session_request(Xml_node);
void _handle_session_requests();
Service_registry _services;
Service_registry _services { };
public:

View File

@ -21,7 +21,7 @@ using namespace Genode;
Native_capability Rpc_entrypoint::_alloc_rpc_cap(Pd_session &pd,
Native_capability ep, addr_t)
Native_capability, addr_t)
{
for (;;) {

View File

@ -37,7 +37,7 @@ class Signal_handler_thread : Thread, Lock
* thread because on some platforms (e.g., Fiasco.OC), the calling
* thread context is used for implementing the signal-source protocol.
*/
Constructible<Signal_source_client> _signal_source;
Constructible<Signal_source_client> _signal_source { };
void entry()
{
@ -68,7 +68,7 @@ class Signal_handler_thread : Thread, Lock
~Signal_handler_thread()
{
env_deprecated()->pd_session()->free_signal_source(*_signal_source);
env_deprecated()->pd_session()->free_signal_source(_signal_source->rpc_cap());
}
};
@ -135,8 +135,8 @@ namespace Genode {
* scalability problem, we might introduce a more sophisticated
* associative data structure.
*/
Lock mutable _lock;
List<List_element<Signal_context> > _list;
Lock mutable _lock { };
List<List_element<Signal_context> > _list { };
public:

View File

@ -26,10 +26,9 @@ using namespace Genode;
************/
Signal::Signal(Signal const &other)
:
_data(other._data.context, other._data.num)
{
_data.context = other._data.context;
_data.num = other._data.num;
_inc_ref();
}

View File

@ -20,7 +20,7 @@ using namespace Genode;
Sliced_heap::Sliced_heap(Ram_allocator &ram_alloc, Region_map &region_map)
:
_ram_alloc(ram_alloc), _region_map(region_map), _consumed(0)
_ram_alloc(ram_alloc), _region_map(region_map)
{ }
@ -80,7 +80,7 @@ bool Sliced_heap::alloc(size_t size, void **out_addr)
}
void Sliced_heap::free(void *addr, size_t size)
void Sliced_heap::free(void *addr, size_t)
{
Ram_dataspace_capability ds_cap;
void *local_addr = nullptr;

View File

@ -45,7 +45,7 @@ addr_t Stack_allocator::idx_to_base(size_t idx)
Stack *
Stack_allocator::alloc(Thread *thread_base, bool main_thread)
Stack_allocator::alloc(Thread *, bool main_thread)
{
if (main_thread)
/* the main-thread stack is the first one */

View File

@ -160,16 +160,7 @@ void Trace::Logger::init(Thread_capability thread, Cpu_session *cpu_session,
}
Trace::Logger::Logger()
:
cpu(nullptr),
control(nullptr),
enabled(false),
policy_version(0),
policy_module(0),
max_event_size(0),
pending_init(false)
{ }
Trace::Logger::Logger() { }
/************

View File

@ -44,8 +44,9 @@ extern "C" void free(void *ptr);
*
* See also: man dl_iterate_phdr
*/
extern "C" int dl_iterate_phdr(int (*callback) (void *info, unsigned long size, void *data), void *data) __attribute__((weak));
extern "C" int dl_iterate_phdr(int (*callback) (void *info, unsigned long size, void *data), void *data) {
extern "C" int dl_iterate_phdr(int (*callback) (void *info, unsigned long size,
void *data), void *data) __attribute__((weak));
extern "C" int dl_iterate_phdr(int (*) (void *, unsigned long, void *), void *) {
return -1; }

View File

@ -216,7 +216,7 @@ extern "C" int strcmp(const char *s1, const char *s2)
/*
* Needed by ARM EABI (gcc-4.4 Codesourcery release1039)
*/
extern "C" int sprintf(char *str, const char *format, ...)
extern "C" int sprintf(char *, const char *, ...)
{
Genode::warning("sprintf - not implemented");
return 0;

View File

@ -92,9 +92,9 @@ struct Linker::Debug
*/
struct Linker::Link_map
{
Elf::Addr addr; /* base address of library */
char const *path; /* path */
void const *dynamic; /* DYNAMIC section */
Elf::Addr addr { }; /* base address of library */
char const *path { nullptr }; /* path */
void const *dynamic { nullptr }; /* DYNAMIC section */
Link_map *next = nullptr;
Link_map *prev = nullptr;

View File

@ -64,6 +64,12 @@ class Linker::Dynamic
private:
/*
* Noncopyable
*/
Dynamic(Dynamic const &);
Dynamic &operator = (Dynamic const &);
struct Needed : Fifo<Needed>::Element
{
off_t offset;
@ -107,7 +113,7 @@ class Linker::Dynamic
Elf::Rel *_rel = nullptr;
unsigned long _rel_size = 0;
Fifo<Needed> _needed;
Fifo<Needed> _needed { };
/**
* \throw Dynamic_section_missing

View File

@ -50,11 +50,11 @@ struct Linker::File
{
typedef void (*Entry)(void);
Phdr phdr;
Entry entry;
Elf::Addr reloc_base = 0;
Elf::Addr start = 0;
Elf::Size size = 0;
Phdr phdr { };
Entry entry { };
Elf::Addr reloc_base { 0 };
Elf::Addr start { 0 };
Elf::Size size { 0 };
virtual ~File() { }
@ -76,8 +76,8 @@ struct Linker::File
struct Linker::Elf_file : File
{
Env &env;
Constructible<Rom_connection> rom_connection;
Rom_dataspace_capability rom_cap;
Constructible<Rom_connection> rom_connection { };
Rom_dataspace_capability rom_cap { };
Ram_dataspace_capability ram_cap[Phdr::MAX_PHDR];
bool const loaded;

View File

@ -116,18 +116,25 @@ namespace Linker {
/**
* Shared object or binary
*/
class Linker::Object : public Fifo<Object>::Element,
public List<Object>::Element
class Linker::Object : private Fifo<Object>::Element,
private List<Object>::Element
{
private:
friend class Fifo<Object>;
friend class List<Object>;
public:
typedef String<128> Name;
protected:
Name _name;
File const *_file = nullptr;
Elf::Addr _reloc_base = 0;
Object *_next_object() const { return List<Object>::Element::next(); }
Name _name { };
File const *_file { nullptr };
Elf::Addr _reloc_base { 0 };
public:
@ -149,7 +156,7 @@ class Linker::Object : public Fifo<Object>::Element,
Elf::Addr reloc_base() const { return _reloc_base; }
char const *name() const { return _name.string(); }
File const *file() const { return _file; }
Elf::Size const size() const { return _file ? _file->size : 0; }
Elf::Size size() const { return _file ? _file->size : 0; }
virtual bool is_linker() const = 0;
virtual bool is_binary() const = 0;
@ -198,6 +205,12 @@ class Linker::Dependency : public Fifo<Dependency>::Element, Noncopyable
{
private:
/*
* Noncopyable
*/
Dependency(Dependency const &);
Dependency &operator = (Dependency const &);
Object &_obj;
Root_object *_root = nullptr;
Allocator *_md_alloc = nullptr;
@ -242,7 +255,7 @@ class Linker::Root_object
{
private:
Fifo<Dependency> _deps;
Fifo<Dependency> _deps { };
Allocator &_md_alloc;

View File

@ -78,19 +78,21 @@ Genode::Lock &Linker::lock()
/**
* The actual ELF object, one per file
*/
class Linker::Elf_object : public Object, public Fifo<Elf_object>::Element
class Linker::Elf_object : public Object, private Fifo<Elf_object>::Element
{
private:
Link_map _map;
unsigned _ref_count = 1;
unsigned const _keep = KEEP;
bool _relocated = false;
friend class Fifo<Elf_object>;
Link_map _map { };
unsigned _ref_count { 1 };
unsigned const _keep { KEEP };
bool _relocated { false };
/*
* Optional ELF file, skipped for initial 'Ld' initialization
*/
Constructible<Elf_file> _elf_file;
Constructible<Elf_file> _elf_file { };
bool _object_init(Object::Name const &name, Elf::Addr reloc_base)
@ -218,9 +220,7 @@ class Linker::Elf_object : public Object, public Fifo<Elf_object>::Element
/**
* Next in initializion list
*/
Object *next_init() const override {
return List<Object>::Element::next();
}
Object *next_init() const override { return _next_object(); }
/**
* Next in object list
@ -249,7 +249,7 @@ class Linker::Elf_object : public Object, public Fifo<Elf_object>::Element
/**
* The dynamic linker object (ld.lib.so)
*/
struct Linker::Ld : Dependency, Elf_object
struct Linker::Ld : private Dependency, Elf_object
{
Ld() :
Dependency(*this, nullptr),
@ -341,8 +341,10 @@ static void exit_on_suspended() { genode_exit(exit_status); }
/**
* The dynamic binary to load
*/
struct Linker::Binary : Root_object, Elf_object
struct Linker::Binary : private Root_object, public Elf_object
{
using Root_object::first_dep;
bool static_construction_finished = false;
Binary(Env &env, Allocator &md_alloc, Bind bind)

View File

@ -50,7 +50,7 @@ class Linker::Reloc_non_plt : public Reloc_non_plt_generic
*addr = (addend ? *addr : 0) + reloc_base + sym->st_value;
}
void _relative(Elf::Rel const *rel, Elf::Addr *addr)
void _relative(Elf::Rel const *, Elf::Addr *addr)
{
if (_dep.obj().reloc_base())
*addr += _dep.obj().reloc_base();

View File

@ -29,7 +29,7 @@ typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
* Implemented in ldso
* */
extern "C" _Unwind_Ptr __attribute__((weak)) dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount);
extern "C" _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount)
extern "C" _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr /* pc */, int * /* pcount */)
{
Genode::error("dl_unwind_find_exidx called");
return 0;