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  <ja...@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

Reply via email to