[C++] Fix up bitfield handling in typeid (PR c++/87547)

Message ID 20181010091731.GT11625@tucnak
State New
Headers show
Series
  • [C++] Fix up bitfield handling in typeid (PR c++/87547)
Related show

Commit Message

Jakub Jelinek Oct. 10, 2018, 9:17 a.m.
Hi!

typeid of an expression that is a bitfield right now returns various weird
results, depending on what exact type ignoring precision we choose for the
bitfield.  Haven't found exact wording in the standard that would back this
out though.  clang++ agrees with the patched g++ though.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2018-10-10  Jakub Jelinek  <jakub@redhat.com>

	PR c++/87547
	* rtti.c (get_tinfo_decl_dynamic): Use unlowered_expr_type instead
	of TREE_TYPE.

	* g++.dg/rtti/typeid12.C: New test.


	Jakub

Comments

Jason Merrill Oct. 11, 2018, 12:18 a.m. | #1
OK.
On Wed, Oct 10, 2018 at 5:17 AM Jakub Jelinek <jakub@redhat.com> wrote:
>
> Hi!
>
> typeid of an expression that is a bitfield right now returns various weird
> results, depending on what exact type ignoring precision we choose for the
> bitfield.  Haven't found exact wording in the standard that would back this
> out though.  clang++ agrees with the patched g++ though.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2018-10-10  Jakub Jelinek  <jakub@redhat.com>
>
>         PR c++/87547
>         * rtti.c (get_tinfo_decl_dynamic): Use unlowered_expr_type instead
>         of TREE_TYPE.
>
>         * g++.dg/rtti/typeid12.C: New test.
>
> --- gcc/cp/rtti.c.jj    2018-08-27 17:50:43.782489578 +0200
> +++ gcc/cp/rtti.c       2018-10-09 10:52:42.348604424 +0200
> @@ -273,7 +273,7 @@ get_tinfo_decl_dynamic (tree exp, tsubst
>    exp = resolve_nondeduced_context (exp, complain);
>
>    /* peel back references, so they match.  */
> -  type = non_reference (TREE_TYPE (exp));
> +  type = non_reference (unlowered_expr_type (exp));
>
>    /* Peel off cv qualifiers.  */
>    type = TYPE_MAIN_VARIANT (type);
> --- gcc/testsuite/g++.dg/rtti/typeid12.C.jj     2018-10-09 10:42:19.580094220 +0200
> +++ gcc/testsuite/g++.dg/rtti/typeid12.C        2018-10-09 10:42:04.105354872 +0200
> @@ -0,0 +1,16 @@
> +// PR c++/87547
> +// { dg-do run }
> +
> +#include <typeinfo>
> +
> +struct S { unsigned int a : 4; unsigned int b : 12; int c; unsigned long d : 8; } s;
> +
> +int
> +main ()
> +{
> +  if (typeid (s.a) != typeid (unsigned int)
> +      || typeid (s.b) != typeid (unsigned int)
> +      || typeid (s.c) != typeid (int)
> +      || typeid (s.d) != typeid (unsigned long))
> +    __builtin_abort ();
> +}
>
>         Jakub

Patch

--- gcc/cp/rtti.c.jj	2018-08-27 17:50:43.782489578 +0200
+++ gcc/cp/rtti.c	2018-10-09 10:52:42.348604424 +0200
@@ -273,7 +273,7 @@  get_tinfo_decl_dynamic (tree exp, tsubst
   exp = resolve_nondeduced_context (exp, complain);
 
   /* peel back references, so they match.  */
-  type = non_reference (TREE_TYPE (exp));
+  type = non_reference (unlowered_expr_type (exp));
 
   /* Peel off cv qualifiers.  */
   type = TYPE_MAIN_VARIANT (type);
--- gcc/testsuite/g++.dg/rtti/typeid12.C.jj	2018-10-09 10:42:19.580094220 +0200
+++ gcc/testsuite/g++.dg/rtti/typeid12.C	2018-10-09 10:42:04.105354872 +0200
@@ -0,0 +1,16 @@ 
+// PR c++/87547
+// { dg-do run }
+
+#include <typeinfo>
+
+struct S { unsigned int a : 4; unsigned int b : 12; int c; unsigned long d : 8; } s;
+
+int
+main ()
+{
+  if (typeid (s.a) != typeid (unsigned int)
+      || typeid (s.b) != typeid (unsigned int)
+      || typeid (s.c) != typeid (int)
+      || typeid (s.d) != typeid (unsigned long))
+    __builtin_abort ();
+}