c++: print source code in print_instantiation_partial_context_line

As mentioned in my Cauldron talk, this patch adds a call to
diagnostic_show_locus to the "required from here" messages
in print_instantiation_partial_context_line, so that e.g., rather
than the rather mystifying:

In file included from ../x86_64-pc-linux-gnu/libstdc++-v3/include/memory:78,
                 from ../../src/demo-1.C:1:
../x86_64-pc-linux-gnu/libstdc++-v3/include/bits/unique_ptr.h: In instantiation of ‘std::__detail::__unique_ptr_t<_Tp> std::make_unique(_Args&& ...) [with _Tp = bar; _Args = {}; __detail::__unique_ptr_t<_Tp> = __detail::__unique_ptr_t<bar>]’:
../../src/demo-1.C:15:32:   required from here
../x86_64-pc-linux-gnu/libstdc++-v3/include/bits/unique_ptr.h:1066:30: error: no matching function for call to ‘bar::bar()’
 1066 |     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/demo-1.C:10:3: note: candidate: ‘bar::bar(int)’
   10 |   bar (int);
      |   ^~~
../../src/demo-1.C:10:3: note:   candidate expects 1 argument, 0 provided
../../src/demo-1.C:7:7: note: candidate: ‘constexpr bar::bar(const bar&)’
    7 | class bar : public foo
      |       ^~~
../../src/demo-1.C:7:7: note:   candidate expects 1 argument, 0 provided
../../src/demo-1.C:7:7: note: candidate: ‘constexpr bar::bar(bar&&)’
../../src/demo-1.C:7:7: note:   candidate expects 1 argument, 0 provided

we emit:

In file included from ../x86_64-pc-linux-gnu/libstdc++-v3/include/memory:78,
                 from ../../src/demo-1.C:1:
../x86_64-pc-linux-gnu/libstdc++-v3/include/bits/unique_ptr.h: In instantiation of ‘std::__detail::__unique_ptr_t<_Tp> std::make_unique(_Args&& ...) [with _Tp = bar; _Args = {}; __detail::__unique_ptr_t<_Tp> = __detail::__unique_ptr_t<bar>]’:
../../src/demo-1.C:15:32:   required from here
   15 |   return std::make_unique<bar> ();
      |          ~~~~~~~~~~~~~~~~~~~~~~^~
../x86_64-pc-linux-gnu/libstdc++-v3/include/bits/unique_ptr.h:1066:30: error: no matching function for call to ‘bar::bar()’
 1066 |     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/demo-1.C:10:3: note: candidate: ‘bar::bar(int)’
   10 |   bar (int);
      |   ^~~
../../src/demo-1.C:10:3: note:   candidate expects 1 argument, 0 provided
../../src/demo-1.C:7:7: note: candidate: ‘constexpr bar::bar(const bar&)’
    7 | class bar : public foo
      |       ^~~
../../src/demo-1.C:7:7: note:   candidate expects 1 argument, 0 provided
../../src/demo-1.C:7:7: note: candidate: ‘constexpr bar::bar(bar&&)’
../../src/demo-1.C:7:7: note:   candidate expects 1 argument, 0 provided

which shows the code that's leading to the error (the bad call to
std::make_unique).

gcc/cp/ChangeLog:
	* error.cc (print_instantiation_partial_context_line): Call
	diagnostic_show_locus.

gcc/testsuite/ChangeLog:
	* g++.dg/diagnostic/static_assert3.C: Add directives for
	additional source printing.
	* g++.dg/template/error60.C: New test.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
David Malcolm 2023-10-03 19:46:33 -04:00
parent 645f2a7dd4
commit 1c45319b66
3 changed files with 45 additions and 1 deletions

View file

@ -3774,6 +3774,8 @@ print_instantiation_partial_context_line (diagnostic_context *context,
? _("recursively required from here\n")
: _("required from here\n"));
}
gcc_rich_location rich_loc (loc);
diagnostic_show_locus (context, &rich_loc, DK_NOTE);
}
/* Same as print_instantiation_full_context but less verbose. */

View file

@ -5,6 +5,11 @@
template <typename T, typename U> struct is_same { static constexpr bool value = false; };
template <typename T> struct is_same<T, T> { static constexpr bool value = true; };
/* { dg-begin-multiline-output "" }
f(0, 1.3);
~^~~~~~~~
{ dg-end-multiline-output "" } */
template <typename T, typename U>
void f(T, U)
{
@ -32,5 +37,5 @@ void f(T, U)
void g()
{
f(0, 1.3);
f(0, 1.3); // { dg-message " required from here" }
}

View file

@ -0,0 +1,37 @@
// { dg-options "-fdiagnostics-show-caret" }
template <typename Foo>
struct my_pointer
{
my_pointer (Foo *ptr) // { dg-message " initializing argument 1" }
: m_ptr (ptr)
{}
Foo *m_ptr;
};
template <typename Foo>
void test (Foo val)
{
my_pointer<Foo> ptr (val); // { dg-error "invalid conversion from 'int' to 'int\\*'" }
}
void usage ()
{
test<int> (42); // { dg-message " required from here" }
/* { dg-begin-multiline-output "" }
test<int> (42);
~~~~~~~~~~^~~~
{ dg-end-multiline-output "" } */
}
/* { dg-begin-multiline-output "" }
my_pointer (Foo *ptr)
~~~~~^~~
{ dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" }
my_pointer<Foo> ptr (val);
^~~
|
int
{ dg-end-multiline-output "" } */