C++: better locations for bogus initializations (PR c++/88375)
authorDavid Malcolm <dmalcolm@redhat.com>
Wed, 19 Dec 2018 15:22:27 +0000 (15:22 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Wed, 19 Dec 2018 15:22:27 +0000 (15:22 +0000)
commit15c40a3b7ce64665f8b4552a45c0cdd9564598cc
tree19d7b2382480d268226940b03efa216e2a1a66a2
parent4c187162fa29f40746b8794bcbc0c4c52a497f31
C++: better locations for bogus initializations (PR c++/88375)

PR c++/88375 reports that errors relating to invalid conversions in
initializations are reported at unhelpfully vague locations, as in
e.g.:

enum struct a : int {
  one, two
};

struct foo {
  int e1, e2;
  a e3;
} arr[] = {
  { 1, 2, a::one },
  { 3, a::two },
  { 4, 5, a::two }
};

for which g++ trunk emits the vague:

pr88375.cc:12:1: error: cannot convert 'a' to 'int' in initialization
   12 | };
      | ^

with the error at the final closing brace.

This patch uses location information for the initializers, converting the
above to:

pr88375.cc:10:11: error: cannot convert 'a' to 'int' in initialization
   10 |   { 3, a::two },
      |        ~~~^~~
      |           |
      |           a

highlighting which subexpression is problematic, and its type.

Ideally we'd also issue a note showing the field decl being initialized,
but that turned out to be more invasive.

gcc/cp/ChangeLog:
PR c++/88375
* typeck.c (convert_for_assignment): Capture location of rhs
before stripping, and if available.  Use the location when
complaining about bad conversions, labelling it with the
rhstype if the location was present.
* typeck2.c (digest_init_r): Capture location of init before
stripping.

gcc/testsuite/ChangeLog:
PR c++/88375
* g++.dg/init/pr88375-2.C: New test.
* g++.dg/init/pr88375.C: New test.

From-SVN: r267276
gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/init/pr88375-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/init/pr88375.C [new file with mode: 0644]