Message ID | 20181010091731.GT11625@tucnak |
---|---|
State | New |
Headers | show |
Series | [C++] Fix up bitfield handling in typeid (PR c++/87547) | expand |
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
--- 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 (); +}