Consider the following code: #include <typeinfo> struct S { unsigned int n4 : 4; unsigned int n12 : 12; }; void f(unsigned char) { std::cout << "uc" << std::endl; } void f(unsigned short) { std::cout << "us" << std::endl; } void f(unsigned int) { std::cout << "ui" << std::endl; } int main(int argc, char* argv[]) { S s; s.n4 = 0; s.n12 = 0; f(s.n4); f(s.n12); std::cout << typeid(s.n4).name() << std::endl; std::cout << typeid(s.n12).name() << std::endl; std::cout << typeid(unsigned char).name() << std::endl; std::cout << typeid(unsigned short).name() << std::endl; std::cout << typeid(unsigned int).name() << std::endl; return 0; } Expected output (according to standard [class.bit] (http://eel.is/c++draft/class.bit): "The bit-field attribute is not part of the type of the class member."): ui ui j j h t j Output produced with g++ (Ubuntu 8.1.0-5ubuntu1~16.04) 8.1.0 (initially discovered with 5.5.0): ui ui h t h t j So while the overload is selected correctly, typeid selects the bad type. I did not test separately, but assume the compiler showing same behaviour for C as well.
(In reply to Sandro Boehler from comment #0) > Expected output (according to standard [class.bit] > (http://eel.is/c++draft/class.bit): "The bit-field attribute is not part of > the type of the class member."): If the bit-field attribute was part of the type then it would be "unsigned int:4" not "unsigned char" or "unsigned short". But G++ is still wrong to use a smaller type, it should be unsigned int (even if internally something else is used).
Created attachment 44816 [details] gcc9-pr87547.patch Untested fix.
Author: jakub Date: Thu Oct 11 07:07:22 2018 New Revision: 265033 URL: https://gcc.gnu.org/viewcvs?rev=265033&root=gcc&view=rev Log: PR c++/87547 * rtti.c (get_tinfo_decl_dynamic): Use unlowered_expr_type instead of TREE_TYPE. * g++.dg/rtti/typeid12.C: New test. Added: trunk/gcc/testsuite/g++.dg/rtti/typeid12.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/rtti.c trunk/gcc/testsuite/ChangeLog
Fixed so closing as such.