aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2002-08-27 22:14:51 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2002-08-27 22:14:51 +0000
commiteca7f13c6953706b97f6158dcef99f0566f1fbb5 (patch)
treeee767505882b4cd0b13a99e8d37e215ba2dcf0f5 /gcc
parentc350f8c1c479aabb1bd0a58f4072381d77daca77 (diff)
downloadgcc-eca7f13c6953706b97f6158dcef99f0566f1fbb5.zip
gcc-eca7f13c6953706b97f6158dcef99f0566f1fbb5.tar.gz
gcc-eca7f13c6953706b97f6158dcef99f0566f1fbb5.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/c-common.c5
-rw-r--r--gcc/c-common.h5
-rw-r--r--gcc/c-opts.c5
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/class.c38
-rw-r--r--gcc/doc/invoke.texi56
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/abi/bitfield5.C14
-rw-r--r--gcc/testsuite/g++.dg/abi/vbase10.C7
10 files changed, 146 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e1d35dd..eafb6a3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+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.
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 875cabc..913aec1 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -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;
diff --git a/gcc/c-common.h b/gcc/c-common.h
index e3e4bb0..b49e2d1 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -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;
diff --git a/gcc/c-opts.c b/gcc/c-opts.c
index bc3ae46..5fb8d11 100644
--- a/gcc/c-opts.c
+++ b/gcc/c-opts.c
@@ -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);
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index def395e..adb6f13 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+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
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index db8cfa7..7cdfdaf 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 1ce61bd..e956baa 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -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
@@ -211,7 +211,7 @@ in the following sections.
@xref{Warning Options,,Options to Request or Suppress Warnings}.
@gccoptlist{
-fsyntax-only -pedantic -pedantic-errors @gol
--w -W -Wall -Waggregate-return @gol
+-w -W -Wall -Waggregate-return @gol
-Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment @gol
-Wconversion -Wno-deprecated-declarations @gol
-Wdisabled-optimization -Wno-div-by-zero -Werror @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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1e3a262..3f3a17d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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.
diff --git a/gcc/testsuite/g++.dg/abi/bitfield5.C b/gcc/testsuite/g++.dg/abi/bitfield5.C
new file mode 100644
index 0000000..eed76e6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/bitfield5.C
@@ -0,0 +1,14 @@
+// { 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;
+};
diff --git a/gcc/testsuite/g++.dg/abi/vbase10.C b/gcc/testsuite/g++.dg/abi/vbase10.C
new file mode 100644
index 0000000..3c110be
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/vbase10.C
@@ -0,0 +1,7 @@
+// { 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" }
+