If i is a volatile int, i++ is an int rvalue. The compiler was treating it as a volatile int rvalue, of which there is no such thing.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit f0049ff597cdeb2437cc9e39f633843bdb12bcba
Author: Jason Merrill <ja...@redhat.com>
Date:   Fri Aug 5 11:57:30 2011 -0400

    	PR c++/49812
    	* typeck.c (cp_build_unary_op) [POSTINCREMENT_EXPR]: Strip cv-quals.

diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index ab08eae..f53deb9 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -5220,6 +5220,9 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
 	      }
 	    val = boolean_increment (code, arg);
 	  }
+	else if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
+	  /* An rvalue has no cv-qualifiers.  */
+	  val = build2 (code, cv_unqualified (TREE_TYPE (arg)), arg, inc);
 	else
 	  val = build2 (code, TREE_TYPE (arg), arg, inc);
 
diff --git a/gcc/testsuite/g++.dg/overload/rvalue2.C b/gcc/testsuite/g++.dg/overload/rvalue2.C
new file mode 100644
index 0000000..8a2290d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/rvalue2.C
@@ -0,0 +1,11 @@
+// PR c++/49812
+// The call should choose the second f because i++ is an int rvalue.
+
+template <class T> void f(const volatile T& t) { t.i; }
+template <class T> void f(const T&);
+
+int main()
+{
+  volatile int i = 0;
+  f(i++);
+}

Reply via email to