In this testcase, in a template we were building a non-dependent version of a COMPONENT_REF with a lowered bit-field type but without the FIELD_DECL. We should use the declared type.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 631e8a030d0c8eebb0800943e41ffbdc38ba7eec Author: Jason Merrill <ja...@redhat.com> Date: Fri Feb 10 15:08:06 2017 -0500 PR c++/78908 - template ops and bitfields * tree.c (build_min_non_dep): Use unlowered_expr_type. diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 785dfaf..56c4bba 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2884,7 +2884,7 @@ build_min_non_dep (enum tree_code code, tree non_dep, ...) t = make_node (code); length = TREE_CODE_LENGTH (code); - TREE_TYPE (t) = TREE_TYPE (non_dep); + TREE_TYPE (t) = unlowered_expr_type (non_dep); TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep); for (i = 0; i < length; i++) diff --git a/gcc/testsuite/g++.dg/template/bitfield3.C b/gcc/testsuite/g++.dg/template/bitfield3.C new file mode 100644 index 0000000..8f11255 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/bitfield3.C @@ -0,0 +1,20 @@ +// PR c++/78908 + +struct A { int a : 1; }; +struct F { int foo (A const &); }; +template <typename> struct O : F { int foo (A const &); }; +struct S {} b; +template <typename L, typename T> int operator<< (L, T) { return (T) 123; } +template <typename T> int O<T>::foo (A const &x) { return b << x.a; } + +int +main () +{ + A a = { 0 }; + O<int> o; + if (o.foo (a) != 123) + __builtin_abort (); + signed char d = 2; + if ((b << d) != 123) + __builtin_abort (); +}