diff options
author | David Malcolm <dmalcolm@redhat.com> | 2018-12-19 15:22:27 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2018-12-19 15:22:27 +0000 |
commit | 15c40a3b7ce64665f8b4552a45c0cdd9564598cc (patch) | |
tree | 19d7b2382480d268226940b03efa216e2a1a66a2 /gcc/testsuite | |
parent | 4c187162fa29f40746b8794bcbc0c4c52a497f31 (diff) | |
download | gcc-15c40a3b7ce64665f8b4552a45c0cdd9564598cc.zip gcc-15c40a3b7ce64665f8b4552a45c0cdd9564598cc.tar.gz gcc-15c40a3b7ce64665f8b4552a45c0cdd9564598cc.tar.bz2 |
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
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/pr88375-2.C | 41 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/pr88375.C | 26 |
3 files changed, 73 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4a61338..b996242 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2018-12-19 David Malcolm <dmalcolm@redhat.com> + PR c++/88375 + * g++.dg/init/pr88375-2.C: New test. + * g++.dg/init/pr88375.C: New test. + +2018-12-19 David Malcolm <dmalcolm@redhat.com> + * c-c++-common/Wtautological-compare-ranges.c: New test. * g++.dg/cpp0x/pr51420.C: Add -fdiagnostics-show-caret and update expected output. diff --git a/gcc/testsuite/g++.dg/init/pr88375-2.C b/gcc/testsuite/g++.dg/init/pr88375-2.C new file mode 100644 index 0000000..97ed72e --- /dev/null +++ b/gcc/testsuite/g++.dg/init/pr88375-2.C @@ -0,0 +1,41 @@ +// { dg-do compile { target c++11 } } +// { dg-options "-fdiagnostics-show-caret" } + +enum struct a : int { + one, two +}; + +constexpr int fn () { return 42; } + +struct foo { + int e1, e2; + a e3; +} arr[] = { + { 3, a::two }, // { dg-error "11: cannot convert 'a' to 'int' in initialization" } + /* { dg-begin-multiline-output "" } + { 3, a::two }, + ~~~^~~ + | + a + { dg-end-multiline-output "" } */ + { 6, 7, fn() }, // { dg-error "13: cannot convert 'int' to 'a' in initialization" } + /* { dg-begin-multiline-output "" } + { 6, 7, fn() }, + ~~^~ + | + int + { dg-end-multiline-output "" } */ +}; + +struct bar { + const char *f1; + int f2; +} arr_2[] = { + { 42 }, // { dg-error "5: invalid conversion from 'int' to 'const char\\*'" } + /* { dg-begin-multiline-output "" } + { 42 }, + ^~ + | + int + { dg-end-multiline-output "" } */ +}; diff --git a/gcc/testsuite/g++.dg/init/pr88375.C b/gcc/testsuite/g++.dg/init/pr88375.C new file mode 100644 index 0000000..21dd6c1 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/pr88375.C @@ -0,0 +1,26 @@ +// { dg-do compile { target c++11 } } + +enum struct a : int { + one, two +}; + +constexpr int fn () { return 42; } + +struct foo { + int e1, e2; + a e3; +} arr[] = { + { 1, 2, a::one }, + { 3, a::two }, // { dg-error "11: cannot convert 'a' to 'int' in initialization" } + { 6, 7, 8 }, // { dg-error "11: cannot convert 'int' to 'a' in initialization" } + { 6, 7, fn() }, // { dg-error "13: cannot convert 'int' to 'a' in initialization" } +}; + +struct bar { + const char *f1; + int f2; +} arr_2[] = { + { "hello world", 42 }, + { 42 }, // { dg-error "5: invalid conversion from 'int' to 'const char\\*'" } + { "hello", "world" }, // { dg-error "14: invalid conversion from 'const char\\*' to 'int'" } +}; |