cxx: remove compilation warnings in C++ code, from both gcc and clang

Summary:
Remove almost all the compilation warnings from C++ code. Only explicit
warnings using the `#warning` preprocessor directive remain.

Some warnings had to be suppressed with `#pragma` directives because the
behavior they were warning about is intended in some specific places.
Code comments were added in such situations.

Added a generator that creates `#pragma` directives in order to suppress
warnings in all generated C++ headers.
Currently `-Wignored-qualifiers` is the only warning category being suppressed.
The innocuous const qualifiers that it points are inoffensive and have
no effect in compilation at all.
They are also hard to track in generation since they can emerge from different
types in many places.

To ease the generation of the warning suppressors an utility constructor was
added to `efl::eolian::grammar::attributes::unused_type`.

Add constructors to `eolian_mono::class_context` to default initialize its
internal string and avoid field initialization warnings.

Test Plan: `meson test`

Reviewers: lauromoura, felipealmeida, zmike, segfaultxavi

Reviewed By: zmike

Subscribers: cedric, #reviewers, #committers

Tags: #efl_language_bindings

Differential Revision: https://phab.enlightenment.org/D9275
This commit is contained in:
Vitor Sousa 2019-07-12 09:07:27 -04:00 committed by Mike Blumenkrantz
parent c001a8146b
commit b1e44484a5
16 changed files with 114 additions and 13 deletions

View File

@ -1,5 +1,5 @@
#ifndef EOLIAN_MONO_EVENTS_HH
#define EOLINA_MONO_EVENTS_HH
#define EOLIAN_MONO_EVENTS_HH
#include <iterator>

View File

@ -21,6 +21,16 @@ struct class_context
};
wrapper_kind current_wrapper_kind;
std::string name;
class_context(wrapper_kind current_wrapper_kind)
: current_wrapper_kind(current_wrapper_kind)
, name()
{}
class_context(wrapper_kind current_wrapper_kind, std::string const& name)
: current_wrapper_kind(current_wrapper_kind)
, name(name)
{}
};
struct indentation_context

View File

@ -183,6 +183,7 @@ struct marshall_type_visitor_generate
, is_out
, is_return
, is_ptr
, false
, is_special_subtype
}(r);
}
@ -195,6 +196,7 @@ struct marshall_type_visitor_generate
, is_out
, is_return
, is_ptr
, false
, is_special_subtype
}(regular);
}
@ -208,6 +210,7 @@ struct marshall_type_visitor_generate
, is_out
, is_return
, is_ptr
, false
, is_special_subtype
}(klass_name);
}
@ -253,7 +256,7 @@ struct marshall_type_visitor_generate
auto default_match = [&] (attributes::complex_type_def const& complex)
{
regular_type_def no_pointer_regular = complex.outer;
return visitor_type{sink, context, c_type, false}(no_pointer_regular)
return visitor_type{sink, context, c_type, false, false, false, false}(no_pointer_regular)
&& as_generator("<" << (type(false, false, true) % ", ") << ">").generate(sink, complex.subtypes, *context);
};
@ -286,6 +289,7 @@ struct marshall_type_visitor_generate
, is_out
, is_return
, is_ptr
, false
, is_special_subtype
}(complex);
}

View File

@ -412,7 +412,7 @@ struct visitor_generate
// pointers.swap(no_pointer_regular.pointers);
// if(is_out)
// pointers.push_back({{attributes::qualifier_info::is_none, {}}, true});
return visitor_type{sink, context, c_type, false}(no_pointer_regular)
return visitor_type{sink, context, c_type, false, false, false, false, false}(no_pointer_regular)
&& as_generator("<" << (type(false, false, true) % ", ") << ">").generate(sink, complex.subtypes, *context)
;
// && detail::generate_pointers(sink, pointers, *context, false);

View File

@ -387,7 +387,15 @@ private:
void _construct(U&& object)
{
assert(!is_engaged());
// NOTE: the buffer memory is intended to be in an
// uninitialized state here.
// So this warning can be disabled.
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
new (&buffer) T(std::forward<U>(object));
#pragma GCC diagnostic pop
engaged = true;
}

View File

@ -293,11 +293,23 @@ void _create_methods_specification_impl(Method const& method, Eldbus_Method2& el
eldbus::_fill_methods(*out_params, method.outs);
// NOTE: C pointer magic performed under the hood requires this conversion
// between incompatible function pointer types.
// C++ always raises a warning for such conversions, so this warning
// can be disabled just here.
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
Eldbus_Method_Cb method_cb =
reinterpret_cast<Eldbus_Method_Cb>
(static_cast<Eldbus_Method_Data_Cb>
(&_method_callback<typename Method::function_type
, typename Method::ins_type, typename Method::outs_type>));
#pragma GCC diagnostic pop
eldbus_method = {{method.name, &(*in_params)[0], &(*out_params)[0]
, reinterpret_cast<Eldbus_Method_Cb>
(static_cast<Eldbus_Method_Data_Cb>
(&_method_callback<typename Method::function_type
, typename Method::ins_type, typename Method::outs_type>))
, method_cb
, ELDBUS_METHOD_FLAG_HAS_DATA}
, new std::tuple<typename Method::function_type
, typename Method::ins_type, typename Method::outs_type

View File

@ -9,7 +9,10 @@ namespace efl { namespace eolian { namespace grammar {
namespace attributes {
struct unused_type {};
struct unused_type {
unused_type() = default;
unused_type(std::nullptr_t) {}
};
unused_type const unused = {};
template <int N, typename Tuple, typename Enable = void>

View File

@ -15,6 +15,7 @@
#include "grammar/type_impl.hpp"
#include "grammar/attribute_reorder.hpp"
#include "grammar/part_implementation.hpp"
#include "grammar/ignore_warning.hpp"
namespace efl { namespace eolian { namespace grammar {
@ -42,6 +43,9 @@ struct class_implementation_generator
.generate(sink, std::make_tuple(cls.namespaces, cls.cxx_name), add_lower_case_context(ctx)))
return false;
if(!as_generator(ignore_warning_begin).generate(sink, nullptr, ctx))
return false;
#ifndef USE_EOCXX_INHERIT_ONLY
if(!as_generator(
(namespaces
@ -71,6 +75,9 @@ struct class_implementation_generator
)).generate(sink, std::make_tuple(cls.namespaces, cls.functions, cpp_namespaces, cls.cxx_name, cls.parts), ctx))
return false;
if(!as_generator(ignore_warning_end).generate(sink, nullptr, ctx))
return false;
if(!as_generator("#endif\n").generate(sink, std::make_tuple(), ctx))
return false;

View File

@ -46,7 +46,7 @@ struct is_eager_generator<T volatile const&> : is_eager_generator<T> {};
// struct is_generator<T> : is_eager_generator<T> {};
template <typename G, typename Enable = typename std::enable_if<is_eager_generator<G>::value>::type>
G as_generator(G&& g) { return g; }
G as_generator(G g) { return g; }
} } }

View File

@ -11,6 +11,7 @@
#include "class_definition.hpp"
#include "class_declaration.hpp"
#include "implementation_include_directive.hpp"
#include "ignore_warning.hpp"
namespace efl { namespace eolian { namespace grammar {
@ -27,11 +28,13 @@ auto class_header =
<< *class_declaration // sequence<class> | class
<< *class_forward_declaration // sequence<class> | class
<< string // extra header <string>
<< ignore_warning_begin
<< "\nnamespace eo_cxx {\n"
<< *base_class_definition // sequence<class> | class
<< "}\n"
<< *class_definition // sequence<class> | class
// << *implementation_include_directive
<< ignore_warning_end
]
;

View File

@ -0,0 +1,48 @@
#ifndef EOLIAN_CXX_IGNORE_WARNING_HH
#define EOLIAN_CXX_IGNORE_WARNING_HH
#include "grammar/generator.hpp"
namespace efl { namespace eolian { namespace grammar {
struct ignore_warning_begin_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::unused_type, Context const& context) const
{
return as_generator(
"\n"
"#pragma GCC diagnostic push\n"
"#pragma GCC diagnostic ignored \"-Wignored-qualifiers\"\n"
"\n"
).generate(sink, nullptr, context);
}
};
struct ignore_warning_end_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::unused_type, Context const& context) const
{
return as_generator(
"\n#pragma GCC diagnostic pop\n\n"
).generate(sink, nullptr, context);
}
};
template <>
struct is_eager_generator<ignore_warning_begin_generator> : std::true_type {};
template <>
struct is_generator<ignore_warning_begin_generator> : std::true_type {};
template <>
struct is_eager_generator<ignore_warning_end_generator> : std::true_type {};
template <>
struct is_generator<ignore_warning_end_generator> : std::true_type {};
ignore_warning_begin_generator constexpr ignore_warning_begin = {};
ignore_warning_end_generator constexpr ignore_warning_end = {};
} } }
#endif

View File

@ -348,7 +348,7 @@ struct visitor_generate
// pointers.swap(no_pointer_regular.pointers);
// if(is_out)
// pointers.push_back({{attributes::qualifier_info::is_none, {}}, true});
return visitor_type{sink, context, c_type, false}(no_pointer_regular)
return visitor_type{sink, context, c_type, false, false}(no_pointer_regular)
&& as_generator("<" << (type % ", ") << ">").generate(sink, complex.subtypes, *context)
;
// && detail::generate_pointers(sink, pointers, *context, false);

View File

@ -126,7 +126,6 @@ ephysics_quaternion_euler_set(EPhysics_Quaternion *quat, double yaw, double pitc
return;
}
bt_quat = btQuaternion();
bt_quat.setEuler(yaw / RAD_TO_DEG, pitch / RAD_TO_DEG, roll / RAD_TO_DEG);
_ephysics_quaternion_update(quat, &bt_quat);
}

View File

@ -14,7 +14,7 @@ void call_async(efl::eina::mutex& mutex, efl::eina::condition_variable& cond, in
{
efl::ecore::main_loop_thread_safe_call_async
(
[&mutex,&cond,&done]
[&mutex,&done]
{
std::cout << "yeah" << std::endl;
efl::eina::unique_lock<efl::eina::mutex> l(mutex);

View File

@ -102,7 +102,14 @@ EFL_START_TEST(eina_cxx_optional_assignment)
assert(!a); assert(b); assert(c); assert(d);
// NOTE: resistance to self assignment is exactly what is being tested here,
// so this compilation warning can be suppressed.
#pragma GCC diagnostic push
#ifdef __clang__
#pragma GCC diagnostic ignored "-Wself-assign-overloaded"
#endif
a = a;
#pragma GCC diagnostic pop
ck_assert(a == a);
ck_assert(!a);

View File

@ -385,7 +385,7 @@ EFL_START_TEST(eina_cxx_ptrlist_constructors)
efl::eina::list<wrapper> list2(10, w1);
ck_assert(list2.size() == 10);
ck_assert(std::find_if(list2.begin(), list2.end()
, [&list2, w2] (wrapper i)
, [w2] (wrapper i)
{
return i == w2;
}