re PR c++/42013 (cv-qualification of conditional expression type depending on the...
authorJason Merrill <jason@redhat.com>
Thu, 12 Nov 2009 18:25:42 +0000 (13:25 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 12 Nov 2009 18:25:42 +0000 (13:25 -0500)
PR c++/42013
* call.c (build_conditional_expr): Don't fold a TREE_SIDE_EFFECTS
COND_EXPR in unevaluated context.

From-SVN: r154124

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/decltype19.C [new file with mode: 0644]

index 9a28a49..e6d696b 100644 (file)
@@ -1,3 +1,9 @@
+2009-11-12  Jason Merrill  <jason@redhat.com>
+
+       PR c++/42013
+       * call.c (build_conditional_expr): Don't fold a TREE_SIDE_EFFECTS
+       COND_EXPR in unevaluated context.
+
 2009-11-12  Jan Hubicka  <jh@suse.cz>
 
        * decl2.c (constrain_visibility): Clear WEAK and COMMON flags.
index db609f8..e77a738 100644 (file)
@@ -3991,8 +3991,13 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
     }
 
  valid_operands:
-  result = fold_if_not_in_template (build3 (COND_EXPR, result_type, arg1,
-                                           arg2, arg3));
+  result = build3 (COND_EXPR, result_type, arg1, arg2, arg3);
+
+  if (cp_unevaluated_operand && TREE_SIDE_EFFECTS (result))
+    /* Avoid folding a ?: of two calls within decltype (c++/42013).  */;
+  else
+    result = fold_if_not_in_template (result);
+
   /* We can't use result_type below, as fold might have returned a
      throw_expr.  */
 
index 94f935d..d5115fd 100644 (file)
@@ -1,3 +1,8 @@
+2009-11-12  Jason Merrill  <jason@redhat.com>
+
+       PR c++/42013
+       * g++.dg/cpp0x/decltype19.C: New.
+
 2009-11-11  Jason Merrill  <jason@redhat.com>
 
        PR c++/39131
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype19.C b/gcc/testsuite/g++.dg/cpp0x/decltype19.C
new file mode 100644 (file)
index 0000000..33ca71f
--- /dev/null
@@ -0,0 +1,24 @@
+// PR c++/42013
+
+template<typename _Tp>
+  _Tp
+declval();
+
+template<typename _Tp, typename _Up>
+  struct common_type
+  {
+    typedef __decltype(true  ? declval<_Tp>() : declval<_Up>()) typet;
+    typedef __decltype(false ? declval<_Tp>() : declval<_Up>()) typef;
+  };
+
+template<typename, typename> struct is_same;
+
+template<typename _Tp> struct is_same<_Tp, _Tp> { typedef _Tp type; };
+
+void f()
+{
+  typedef common_type<int, const int>::typet typet;
+  typedef common_type<int, const int>::typef typef;
+
+  typedef is_same<typet, typef>::type type;
+}