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

@ -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;