[Bug c++/54348] confusing error reported for type mismatch in conditional expression : error: no match for ternary 'operator?:' in 'false ?

2014-05-09 Thread jason at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54348

--- Comment #10 from Jason Merrill jason at gcc dot gnu.org ---
Author: jason
Date: Fri May  9 18:15:57 2014
New Revision: 210282

URL: http://gcc.gnu.org/viewcvs?rev=210282root=gccview=rev
Log:
PR c++/32019
* call.c (build_conditional_expr_1): Improve ambiguity diagnostic.

PR c++/54348
* call.c (build_conditional_expr_1): If overload resolution finds
no match, just say different types.

Added:
trunk/gcc/testsuite/g++.dg/expr/cond10.C
trunk/gcc/testsuite/g++.dg/expr/cond11.C
trunk/gcc/testsuite/g++.dg/expr/cond13.C
Modified:
trunk/gcc/cp/ChangeLog
trunk/gcc/cp/call.c
trunk/gcc/testsuite/g++.dg/cpp0x/explicit3.C
trunk/gcc/testsuite/g++.dg/parse/crash41.C


[Bug c++/54348] confusing error reported for type mismatch in conditional expression : error: no match for ternary 'operator?:' in 'false ?

2014-05-09 Thread jason at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54348

Jason Merrill jason at gcc dot gnu.org changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||jason at gcc dot gnu.org
 Resolution|--- |FIXED
   Assignee|unassigned at gcc dot gnu.org  |jason at gcc dot gnu.org
   Target Milestone|--- |4.10.0

--- Comment #11 from Jason Merrill jason at gcc dot gnu.org ---
Fixed to just say different types.


[Bug c++/54348] confusing error reported for type mismatch in conditional expression : error: no match for ternary 'operator?:' in 'false ?

2012-08-22 Thread redi at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54348

--- Comment #9 from Jonathan Wakely redi at gcc dot gnu.org 2012-08-22 
07:37:18 UTC ---
(In reply to comment #5)
   strct s  struct_strct( items, myItems, name, myName ) ;
 }
 /code
 
 This works!

Only because NULL can be converted to std::string - but it would crash at
runtime if that branch was taken.


(In reply to comment #7)
  void f()
  {
  false ? a : b;
  }
 
 but this is not the same. surely ? the above is not a valid statement -

It's exactly the same. It's not valid because the types are incompatible, just
like your example. e.g. this is fine:

  false ? a : a;

 I was saying:
 
   some_type some_object = false ? a : b;

As I said previously, the fact the conditional expression is used as an
initializer is irrelevant to the error.


(In reply to comment #8)
 All I'm suggesting is that g++ should try to find the most basic error, 

Exactly. And the error is in the conditional expression, it has nothing to do
with the object being initialized.


 which is that different type objects are returned as the result of a
 conditional expression, and not  no match for ternary 'operator?:' -
 what does this mean, it was searching namespace std:: for string::operator::?:
 ?
 then this succeeded, and it found it could not apply it because the types
 were different - shouldn't it complain about the root cause, that the types
 were different, rather than the symptom of not being able to satisfy
 operator std::string::?:() ?

It *is* complaining that the types are different (just not very clearly.)
The error has nothing to do with the type being initialized.

Here's a simpler form of your original which might convince you of that:

#include string
#include list
using namespace std;
void f()
{
  list string myItems;
  string myName;
  false ? myItems : myName;
}

This still gives the same error. Understand now?


[Bug c++/54348] confusing error reported for type mismatch in conditional expression : error: no match for ternary 'operator?:' in 'false ?

2012-08-21 Thread paolo.carlini at oracle dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54348

Paolo Carlini paolo.carlini at oracle dot com changed:

   What|Removed |Added

   Keywords||diagnostic
 Status|UNCONFIRMED |NEW
   Last reconfirmed||2012-08-21
Summary|wrong error reported for|confusing error reported
   |type mismatch in|for type mismatch in
   |conditional expression :|conditional expression :
   |error: no match for|error: no match for
   |ternary 'operator?:' in |ternary 'operator?:' in
   |'false ?   |'false ?
 Ever Confirmed|0   |1

--- Comment #1 from Paolo Carlini paolo.carlini at oracle dot com 2012-08-21 
19:44:55 UTC ---
In mainline the diagnostics is better because we output the types. But I agree
that given that the conditional operator cannot be overloaded the error message
could be more clear.


[Bug c++/54348] confusing error reported for type mismatch in conditional expression : error: no match for ternary 'operator?:' in 'false ?

2012-08-21 Thread redi at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54348

--- Comment #2 from Jonathan Wakely redi at gcc dot gnu.org 2012-08-21 
19:51:53 UTC ---
(In reply to comment #0)
 Shouldn't g++ be complaining about initializing a string with a liststring
 rather than this cryptic no match for ternary 'operator?:' here ?

No, not really.

The object being initialized by the result of the condition expression is
irrelevant, the conditional expression isn't valid whether or not you're using
it to initialize another object.

In this reduced version it wouldn't make sense to refer to initializing any
object with any other:

struct A {} a;
struct B {} b;

void f()
{
false ? a : b;
}


[Bug c++/54348] confusing error reported for type mismatch in conditional expression : error: no match for ternary 'operator?:' in 'false ?

2012-08-21 Thread paolo.carlini at oracle dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54348

--- Comment #3 from Paolo Carlini paolo.carlini at oracle dot com 2012-08-21 
20:08:02 UTC ---
Indeed.

About my own reply, I'm not sure, the wording here is pretty subtle, we already
handle separately the ambiguous overloading case. ICC refers explicitly to the
types being incompatible, maybe focusing on the types is more clear when the
operator at issue cannot be overloaded.


[Bug c++/54348] confusing error reported for type mismatch in conditional expression : error: no match for ternary 'operator?:' in 'false ?

2012-08-21 Thread redi at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54348

--- Comment #4 from Jonathan Wakely redi at gcc dot gnu.org 2012-08-21 
20:24:15 UTC ---
I think clang's incompatible operand types is simple and fairly clear


[Bug c++/54348] confusing error reported for type mismatch in conditional expression : error: no match for ternary 'operator?:' in 'false ?

2012-08-21 Thread jason.vas.dias at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54348

--- Comment #5 from Jason Vas Dias jason.vas.dias at gmail dot com 2012-08-21 
20:27:36 UTC ---
Oops, I was interrupted adding this comment to my initial comment - will
respond
to subsequent commment next :

Incidentally, I found this issue while developing a C++-98 replacement for
C-99 designated initializers for specific structs with generated macros :
code
#include string
#include list
using namespace std;

struct strct 
{
string name, items ;
strct (string n, string i) : name(n), items(i){}
};

#define tok(t) t

#define the_struct_strct_member( member, a0, a1, a2, a3 )\
( struct strct*)0) - member ) == (((struct strct*)0) - a0)) \
   ? a1\
   :( ( (((struct strct*)0) - member) ==  (((struct strct*)0) - a2) ) \
  ? a3\
  : NULL\
)\
)

#define struct_strct( a0, a1, a2, a3 )\
(the_struct_strct_member( tok(name)  , a0, a1, a2, a3 ),\
 the_struct_strct_member( tok(items) , a0, a1, a2, a3 )\
)

void f()
{

  string myItems;
  string myName();

  strct s  struct_strct( items, myItems, name, myName ) ;
}
/code

This works!


[Bug c++/54348] confusing error reported for type mismatch in conditional expression : error: no match for ternary 'operator?:' in 'false ?

2012-08-21 Thread jason.vas.dias at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54348

--- Comment #6 from Jason Vas Dias jason.vas.dias at gmail dot com 2012-08-21 
20:29:53 UTC ---
(In reply to comment #1)
 In mainline the diagnostics is better because we output the types. But I agree
 that given that the conditional operator cannot be overloaded the error 
 message
 could be more clear.

yes, that is all I'm saying


[Bug c++/54348] confusing error reported for type mismatch in conditional expression : error: no match for ternary 'operator?:' in 'false ?

2012-08-21 Thread jason.vas.dias at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54348

--- Comment #7 from Jason Vas Dias jason.vas.dias at gmail dot com 2012-08-21 
20:34:06 UTC ---
(In reply to comment #2)
 (In reply to comment #0)
  Shouldn't g++ be complaining about initializing a string with a liststring
  rather than this cryptic no match for ternary 'operator?:' here ?
 
 No, not really.
 
 The object being initialized by the result of the condition expression is
 irrelevant, the conditional expression isn't valid whether or not you're using
 it to initialize another object.
 
 In this reduced version it wouldn't make sense to refer to initializing any
 object with any other:
 
 struct A {} a;
 struct B {} b;
 
 void f()
 {
 false ? a : b;
 }

but this is not the same. surely ? the above is not a valid statement -
I was saying:

  some_type some_object = false ? a : b;


[Bug c++/54348] confusing error reported for type mismatch in conditional expression : error: no match for ternary 'operator?:' in 'false ?

2012-08-21 Thread jason.vas.dias at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54348

--- Comment #8 from Jason Vas Dias jason.vas.dias at gmail dot com 2012-08-21 
20:52:12 UTC ---
All I'm suggesting is that g++ should try to find the most basic error, 
which is that different type objects are returned as the result of a
conditional expression, and not  no match for ternary 'operator?:' -
what does this mean, it was searching namespace std:: for string::operator::?:
?
then this succeeded, and it found it could not apply it because the types
were different - shouldn't it complain about the root cause, that the types
were different, rather than the symptom of not being able to satisfy
operator std::string::?:() ?