From ca45eca116b838230e9b169c2ee5579190593af8 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 22 Apr 2013 15:25:23 -0400 Subject: [PATCH] N3323 * cvt.c (build_expr_type_conversion): Two conversions that return the same type aren't necessarily ambiguous. From-SVN: r198157 --- gcc/cp/ChangeLog | 4 +++ gcc/cp/cvt.c | 23 ++++++++++------ gcc/testsuite/g++.dg/cpp1y/context-conv1.C | 32 ++++++++++++++++++++++ 3 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/context-conv1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 34f207f364b..57c2fc3f571 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2013-04-22 Jason Merrill + N3323 + * cvt.c (build_expr_type_conversion): Two conversions that return + the same type aren't necessarily ambiguous. + N3648 * parser.c (cp_parser_lambda_introducer): Make lambda capture init pedwarn unconditional except in C++1y mode. diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index a3b73580b23..93be76a6c05 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -1630,17 +1630,24 @@ build_expr_type_conversion (int desires, tree expr, bool complain) { if (winner) { - if (complain) + tree winner_type + = non_reference (TREE_TYPE (TREE_TYPE (winner))); + + if (!same_type_ignoring_top_level_qualifiers_p (winner_type, + candidate)) { - error ("ambiguous default type conversion from %qT", - basetype); - error (" candidate conversions include %qD and %qD", - winner, cand); + if (complain) + { + error ("ambiguous default type conversion from %qT", + basetype); + error (" candidate conversions include %qD and %qD", + winner, cand); + } + return error_mark_node; } - return error_mark_node; } - else - winner = cand; + + winner = cand; } } diff --git a/gcc/testsuite/g++.dg/cpp1y/context-conv1.C b/gcc/testsuite/g++.dg/cpp1y/context-conv1.C new file mode 100644 index 00000000000..fe20cab3c26 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/context-conv1.C @@ -0,0 +1,32 @@ +// N3323 + +#define assert(E) if(!(E))__builtin_abort(); + +template +class zero_init +{ +public: + zero_init( ) + : val( static_cast(0) ) { } + zero_init( T val ) : val( val ) + { } + operator T & ( ) { return val; } + operator T ( ) const { return val; } +private: + T val; +}; + +void f() +{ + zero_init p; assert( p == 0 ); + p = new int(7); + assert( *p == 7 ); + delete p; // error! + + zero_init i; assert( i == 0 ); + i = 7; + assert( i == 7 ); + switch( i ) { } // error! + + int *vp = new int[i]; +} -- 2.30.2