Commit eca7f13c by Mark Mitchell Committed by Mark Mitchell

c-common.c (warn_abi): New variable.

	* c-common.c (warn_abi): New variable.
	* c-common.h (warn_abi): Likewise.
	* c-opts.c (COMMAND_LINE_OPTIONS): Add -Wabi.
	(c_common_decode_option): Handle it.
	* doc/invoke.texi:P Document -Wabi.

	* class.c (layout_virtual_bases): Warn about bugs in G++ that
	result in incorrect object layouts.
	(layout_class_type): Likewise.

	* testsuite/g++.dg/abi/bitfield5.C: New test.
	* testsuite/g++.dg/abi/vbase10.C: Likewise.

From-SVN: r56618
parent c350f8c1
2002-08-27 Mark Mitchell <mark@codesourcery.com>
* c-common.c (warn_abi): New variable.
* c-common.h (warn_abi): Likewise.
* c-opts.c (COMMAND_LINE_OPTIONS): Add -Wabi.
(c_common_decode_option): Handle it.
* doc/invoke.texi:P Document -Wabi.
Tue Aug 27 23:03:52 2002 Nicola Pero <n.pero@mi.flashnet.it>
* c-common.c (warn_undeclared_selector): New variable.
......
......@@ -566,6 +566,11 @@ int flag_permissive;
int flag_enforce_eh_specs = 1;
/* Nonzero means warn about things that will change when compiling
with an ABI-compliant compiler. */
int warn_abi = 0;
/* Nonzero means warn about implicit declarations. */
int warn_implicit = 1;
......
......@@ -737,6 +737,11 @@ extern int flag_permissive;
extern int flag_enforce_eh_specs;
/* Nonzero means warn about things that will change when compiling
with an ABI-compliant compiler. */
extern int warn_abi;
/* Nonzero means warn about implicit declarations. */
extern int warn_implicit;
......
......@@ -124,6 +124,7 @@ static void sanitize_cpp_opts PARAMS ((void));
OPT("MQ", CL_ALL | CL_ARG, OPT_MQ) \
OPT("MT", CL_ALL | CL_ARG, OPT_MT) \
OPT("P", CL_ALL, OPT_P) \
OPT("Wabi", CL_CXX, OPT_Wabi) \
OPT("Wall", CL_ALL, OPT_Wall) \
OPT("Wbad-function-cast", CL_C, OPT_Wbad_function_cast) \
OPT("Wcast-qual", CL_ALL, OPT_Wcast_qual) \
......@@ -684,6 +685,10 @@ c_common_decode_option (argc, argv)
cpp_opts->no_line_commands = 1;
break;
case OPT_Wabi:
warn_abi = on;
break;
case OPT_Wall:
set_Wunused (on);
set_Wformat (on);
......
2002-08-27 Mark Mitchell <mark@codesourcery.com>
* class.c (layout_virtual_bases): Warn about bugs in G++ that
result in incorrect object layouts.
(layout_class_type): Likewise.
2002-08-24 Matt Austern <austern@apple.com>
* tree.c (lvalue_p_1): Add argument for whether casts of lvalues
......
......@@ -4562,6 +4562,7 @@ layout_virtual_bases (t, offsets)
{
tree vbases, dsize;
unsigned HOST_WIDE_INT eoc;
bool first_vbase = true;
if (CLASSTYPE_N_BASECLASSES (t) == 0)
return;
......@@ -4589,6 +4590,7 @@ layout_virtual_bases (t, offsets)
if (!TREE_VIA_VIRTUAL (vbases))
continue;
vbase = binfo_for_vbase (BINFO_TYPE (vbases), t);
if (!BINFO_PRIMARY_P (vbase))
......@@ -4606,7 +4608,6 @@ layout_virtual_bases (t, offsets)
/* Add padding so that we can put the virtual base class at an
appropriately aligned offset. */
dsize = round_up (dsize, desired_align);
usize = size_binop (CEIL_DIV_EXPR, dsize, bitsize_unit_node);
/* We try to squish empty virtual bases in just like
......@@ -4634,11 +4635,30 @@ layout_virtual_bases (t, offsets)
CLASSTYPE_SIZE (basetype)));
}
/* If the first virtual base might have been placed at a
lower address, had we started from CLASSTYPE_SIZE, rather
than TYPE_SIZE, issue a warning. There can be both false
positives and false negatives from this warning in rare
cases; to deal with all the possibilities would probably
require performing both layout algorithms and comparing
the results which is not particularly tractable. */
if (warn_abi
&& first_vbase
&& tree_int_cst_lt (size_binop (CEIL_DIV_EXPR,
round_up (CLASSTYPE_SIZE (t),
desired_align),
bitsize_unit_node),
BINFO_OFFSET (vbase)))
warning ("offset of virtual base `%T' is not ABI-compliant and may change in a future version of GCC",
basetype);
/* Keep track of the offsets assigned to this virtual base. */
record_subobject_offsets (BINFO_TYPE (vbase),
BINFO_OFFSET (vbase),
offsets,
/*vbases_p=*/0);
first_vbase = false;
}
}
......@@ -4776,6 +4796,8 @@ layout_class_type (t, empty_p, vfuns_p, virtuals_p)
/* Maps offsets (represented as INTEGER_CSTs) to a TREE_LIST of
types that appear at that offset. */
splay_tree empty_base_offsets;
/* True if the last field layed out was a bit-field. */
bool last_field_was_bitfield = false;
/* Keep track of the first non-static data member. */
non_static_data_members = TYPE_FIELDS (t);
......@@ -4865,6 +4887,18 @@ layout_class_type (t, empty_p, vfuns_p, virtuals_p)
layout_nonempty_base_or_field (rli, field, NULL_TREE,
empty_base_offsets, t);
/* If a bit-field does not immediately follow another bit-field,
and yet it starts in the middle of a byte, we have failed to
comply with the ABI. */
if (warn_abi
&& DECL_C_BIT_FIELD (field)
&& !last_field_was_bitfield
&& !integer_zerop (size_binop (TRUNC_MOD_EXPR,
DECL_FIELD_BIT_OFFSET (field),
bitsize_unit_node)))
cp_warning_at ("offset of `%D' is not ABI-compliant and may change in a future version of GCC",
field);
/* If we needed additional padding after this field, add it
now. */
if (padding)
......@@ -4882,6 +4916,8 @@ layout_class_type (t, empty_p, vfuns_p, virtuals_p)
NULL_TREE,
empty_base_offsets, t);
}
last_field_was_bitfield = DECL_C_BIT_FIELD (field);
}
/* It might be the case that we grew the class to allocate a
......
......@@ -187,7 +187,7 @@ in the following sections.
-fno-optional-diags -fpermissive @gol
-frepo -fno-rtti -fstats -ftemplate-depth-@var{n} @gol
-fuse-cxa-atexit -fvtable-gc -fno-weak -nostdinc++ @gol
-fno-default-inline -Wctor-dtor-privacy @gol
-fno-default-inline -Wabi -Wctor-dtor-privacy @gol
-Wnon-virtual-dtor -Wreorder @gol
-Weffc++ -Wno-deprecated @gol
-Wno-non-template-friend -Wold-style-cast @gol
......@@ -1475,6 +1475,58 @@ Do not assume @samp{inline} for functions defined inside a class scope.
functions will have linkage like inline functions; they just won't be
inlined by default.
@item -Wabi @r{(C++ only)}
@opindex Wabi
Warn when G++ generates code that is probably not compatible with the
vendor-neutral C++ ABI. Although an effort has been made to warn about
all such cases, there are probably some cases that are not warned about,
even though G++ is generating incompatible code. There may also be
cases where warnings are emitted even though the code that is generated
will be compatible.
You should rewrite your code to avoid these warnings if you are
concerned about the fact that code generated by G++ may not be binary
compatible with code generated by other compilers.
The known incompatibilites at this point include:
@itemize @bullet
@item
Incorrect handling of tail-padding for bit-fields. G++ may attempt to
pack data into the same byte as a base class. For example:
@smallexample
struct A @{ virtual void f(); int f1 : 1; @};
struct B : public A @{ int f2 : 1; @};
@end smallexample
@noindent
In this case, G++ will place @code{B::f2} into the same byte
as@code{A::f1}; other compilers will not. You can avoid this problem
by explicitly padding @code{A} so that its size is a multiple of the
byte size on your platform; that will cause G++ and other compilers to
layout @code{B} identically.
@item
Incorrect handling of tail-padding for virtual bases. G++ does not use
tail padding when laying out virtual bases. For example:
@smallexample
struct A @{ virtual void f(); char c1; @};
struct B @{ B(); char c2; @};
struct C : public A, public virtual B @{@};
@end smallexample
@noindent
In this case, G++ will not place @code{B} into the tail-padding for
@code{A}; other compilers will. You can avoid this problem by
explicitly padding @code{A} so that its size is a multiple of its
alignment (ignoring virtual base classes); that will cause G++ and other
compilers to layout @code{C} identically.
@end itemize
@item -Wctor-dtor-privacy @r{(C++ only)}
@opindex Wctor-dtor-privacy
Warn when a class seems unusable, because all the constructors or
......
2002-08-27 Mark Mitchell <mark@codesourcery.com>
* testsuite/g++.dg/abi/bitfield5.C: New test.
* testsuite/g++.dg/abi/vbase10.C: Likewise.
Tue Aug 27 22:23:22 2002 Nicola Pero <n.pero@mi.flashnet.it>
* objc.dg/undeclared-selector.m: New test.
......
// { dg-do compile }
// { dg-options "-Wabi" }
struct A {
virtual void f();
int f1 : 1;
};
struct B : public A {
int f2 : 1; // { dg-warning "ABI" }
int : 0;
int f3 : 4;
int f4 : 3;
};
// { dg-do compile }
// { dg-options "-Wabi" }
struct A { virtual void f(); char c1; };
struct B { B(); char c2; };
struct C : public A, public virtual B {}; // { dg-warning "ABI" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment