diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9a28a4960ed..e6d696b0447 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2009-11-12 Jason Merrill + + 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 * decl2.c (constrain_visibility): Clear WEAK and COMMON flags. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index db609f8015e..e77a738660d 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 94f935d80d9..d5115fd09ac 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-11-12 Jason Merrill + + PR c++/42013 + * g++.dg/cpp0x/decltype19.C: New. + 2009-11-11 Jason Merrill 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 index 00000000000..33ca71ff492 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype19.C @@ -0,0 +1,24 @@ +// PR c++/42013 + +template + _Tp +declval(); + +template + struct common_type + { + typedef __decltype(true ? declval<_Tp>() : declval<_Up>()) typet; + typedef __decltype(false ? declval<_Tp>() : declval<_Up>()) typef; + }; + +template struct is_same; + +template struct is_same<_Tp, _Tp> { typedef _Tp type; }; + +void f() +{ + typedef common_type::typet typet; + typedef common_type::typef typef; + + typedef is_same::type type; +}