From: Mark Mitchell Date: Tue, 27 Aug 2002 22:49:49 +0000 (+0000) Subject: invoke.texi: Document -Wabi. X-Git-Tag: releases/gcc-3.2.1~350 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b2750f75e462cc767a346a5e69bb2d88c23b0344;p=thirdparty%2Fgcc.git invoke.texi: Document -Wabi. 2002-08-27 Mark Mitchell * doc/invoke.texi: Document -Wabi. 2002-08-27 Mark Mitchell * cp-tree.h (warn_abi): Declare it. * decl.c (warn_abi): Define it. (cxx_decode_option): Set it. * class.c (layout_virtual_bases): Warn about bugs in G++ that result in incorrect object layouts. (layout_class_type): Likewise. 2002-08-27 Mark Mitchell * testsuite/g++.dg/abi/bitfield5.C: New test. * testsuite/g++.dg/abi/vbase10.C: Likewise. From-SVN: r56623 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6cd1b836a755..4bd213dc7cc8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2002-08-27 Mark Mitchell + + * doc/invoke.texi: Document -Wabi. + 2002-08-23 David Edelsohn * config/rs6000/rs6000.c (rs6000_select_section): Treat diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8e84fe6f62e5..e7c5b8c5316d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2002-08-27 Mark Mitchell + + * cp-tree.h (warn_abi): Declare it. + * decl.c (warn_abi): Define it. + (cxx_decode_option): Set it. + * class.c (layout_virtual_bases): Warn about bugs in G++ that + result in incorrect object layouts. + (layout_class_type): Likewise. + 2002-08-22 Jason Merrill PR c++/5607 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index f655846e060c..2395d794bfc7 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -4557,6 +4557,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; @@ -4584,6 +4585,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)) @@ -4601,7 +4603,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 @@ -4629,11 +4630,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; } } @@ -4771,6 +4791,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); @@ -4860,6 +4882,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) @@ -4877,6 +4911,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/cp/cp-tree.h b/gcc/cp/cp-tree.h index 48b615bf8d79..787114f492b4 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -934,6 +934,11 @@ extern int flag_operator_names; extern int flag_gnu_binutils; +/* 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/cp/decl2.c b/gcc/cp/decl2.c index 499ff73b9f59..09a30f4a007f 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -172,6 +172,11 @@ int flag_implicit_templates = 1; int flag_implicit_inline_templates = 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; @@ -600,7 +605,9 @@ cxx_decode_option (argc, argv) if (p[0] == 'n' && p[1] == 'o' && p[2] == '-') setting = 0, p += 3; - if (!strcmp (p, "implicit")) + if (!strcmp (p, "abi")) + warn_abi = setting; + else if (!strcmp (p, "implicit")) warn_implicit = setting; else if (!strcmp (p, "long-long")) warn_long_long = setting; diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 0fbea884fa05..a3b53ed3822c 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 -Wdiv-by-zero -Werror @gol @@ -1551,6 +1551,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 b15075dbac50..d70091b663a4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2002-08-27 Mark Mitchell + + * testsuite/g++.dg/abi/bitfield5.C: New test. + * testsuite/g++.dg/abi/vbase10.C: Likewise. + 2002-08-15 Neil Booth * gcc.dg/cpp/_Pragma3.c, gcc.dg/cpp/vararg3.c, gcc.dg/cpp/vararg4.c: