aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-02-10 15:43:33 -0500
committerJason Merrill <jason@gcc.gnu.org>2017-02-10 15:43:33 -0500
commit6a2cc46b799d01c8abbc98c70b1bacca9fd7bc2d (patch)
tree8fc81895d35ce55da75a08cb4d3283704d9d8f9b /gcc
parent5c97093ba7feef2235c45233a2a1175c8c168b4c (diff)
downloadgcc-6a2cc46b799d01c8abbc98c70b1bacca9fd7bc2d.zip
gcc-6a2cc46b799d01c8abbc98c70b1bacca9fd7bc2d.tar.gz
gcc-6a2cc46b799d01c8abbc98c70b1bacca9fd7bc2d.tar.bz2
PR c++/78908 - template ops and bitfields
* tree.c (build_min_non_dep): Use unlowered_expr_type. From-SVN: r245343
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/tree.c2
-rw-r--r--gcc/testsuite/g++.dg/template/bitfield3.C20
3 files changed, 24 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index be51428..4523d12 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,8 @@
2017-02-10 Jason Merrill <jason@redhat.com>
+ PR c++/78908 - template ops and bitfields
+ * tree.c (build_min_non_dep): Use unlowered_expr_type.
+
PR c++/78897 - constexpr union
* constexpr.c (cxx_eval_store_expression): A store to a union member
erases a previous store to another member.
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 ();
+}