Bug 45333 - Include macros in instantiation backtraces
Summary: Include macros in instantiation backtraces
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: unknown
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2010-08-19 04:52 UTC by Ollie Wild
Modified: 2021-12-08 15:28 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-10-20 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ollie Wild 2010-08-19 04:52:30 UTC
Consider the following code sample:


#define ZERO(c) c.set(0)

struct S
{
 int a;
 int b;
};

template <class T>
class C
{
 T t;

public:
 void set(int x) { t = x; }
};

void foo(C<S> &c)
{
 ZERO(c);
}


When compiled with clang, the instantiation backtrace shows the point of instantiation within the ZERO macro:

#> clang ./tst.cc
./tst.cc:15:23: error: no viable overloaded '='
 void set(int x) { t = x; }
                   ~ ^ ~
./tst.cc:20:3: note: in instantiation of member function 'C<struct S>::set'
     requested here
 ZERO(c);
 ^
./tst.cc:1:19: note: instantiated from:
#define ZERO(c) c.set(0)
                 ^
./tst.cc:3:8: note: candidate function (the implicit copy assignment operator)
     not viable: no known conversion from 'int' to 'struct S const' for 1st
     argument
struct S
      ^
3 diagnostics generated.


By contract, gcc ignores the macro completely:

#> ./install/bin/gcc -c ./tst.cc
./tst.cc: In member function ‘void C<T>::set(int) [with T = S]’:
./tst.cc:20:3:   instantiated from here
./tst.cc:15:21: error: no match for ‘operator=’ in ‘this->C<S>::t = x’
./tst.cc:3:8: note: candidate is: S& S::operator=(const S&)

GCC should include macros in instantiation backtraces like clang does.
Comment 1 Paolo Carlini 2011-10-20 01:30:22 UTC
Sorry for being naive, Dodji, has this anything to do with your recent work? It's still untriaged.
Comment 2 dodji@seketeli.org 2011-10-20 08:25:20 UTC
Yes, it's related.  With the infrastructure that is in right now, the
results are not super for template instantiate backtraces though:

$ cat -n test.cc
     1	#define ZERO(c) c.set(0)
     2	
     3	struct S
     4	{
     5	  int a;
     6	  int b;
     7	};
     8	
     9	template <class T>
    10	class C
    11	{
    12	  T t;
    13	
    14	public:
    15	  void set(int x) { t = x; }
    16	};
    17	
    18	void foo(C<S> &c)
    19	{
    20	  ZERO(c);
    21	}
    22	
    23	
    24	
$ 

When  cc1plus -quiet -ftrack-macro-expansion ./test.cc yields:

test.cc: In instantiation of ‘void C<T>::set(int) [with T = S]’:
test.cc:1:24:   required from here
test.cc:15:21: erreur: no match for ‘operator=’ in ‘((C<S>*)this)->C<S>::t = x’
test.cc:15:21: note: candidate is:
test.cc:3:8: note: S& S::operator=(const S&)
test.cc:3:8: note:   no known conversion for argument 1 from ‘int’ to ‘const S&’

So it points to the spelling location (1:24) of the token involved in
the error message, rather than to the expansion point of the macro.  I'd
like it to mention both, like it does for the C FE.

Beside fixing the various bootstrap breakages I have introduced, I'll
need to go through the template instantiation error message mechanics to
teach them how to use the new macro token tracking infrastructure, I
guess.  :-)

At least we have the infrastructure now.

Thank you for the head-up.
Comment 3 Manuel López-Ibáñez 2011-10-20 08:32:40 UTC
With -ftrack-macro-expansion we get:

pr45333.cc: In instantiation of ‘void C<T>::set(int) [with T = S]’:
pr45333.cc:1:24:   required from here
pr45333.cc:15:21: error: no match for ‘operator=’ in ‘((C<S>*)this)->C<S>::t = x’
pr45333.cc:15:21: note: candidate is:
pr45333.cc:3:8: note: S& S::operator=(const S&)
pr45333.cc:3:8: note:   no known conversion for argument 1 from ‘int’ to ‘const S&’

So we can track the origin of the instantation to the macro definition, but then we don't show where the macro is invoked from, which is shown without -ftrack-macro-expansion. I think it should show both, like clang does:

pr45333.cc: In instantiation of ‘void C<T>::set(int) [with T = S]’:
pr45333.cc:1:19:   instantiated from macro ZERO
pr45333.cc:20:3:   required from here
pr45333.cc:15:21: error: no match for ‘operator=’ in ‘((C<S>*)this)->C<S>::t = x’
pr45333.cc:15:21: note: candidate is:
pr45333.cc:3:8: note: S& S::operator=(const S&)
pr45333.cc:3:8: note:   no known conversion for argument 1 from ‘int’ to ‘const S&’

Notice that in my ideal output, I also fixed the location given for the first instantation to point to "set" (1:19) and not to the end of the line (1:24).
Comment 4 dodji@seketeli.org 2011-10-20 08:57:06 UTC
> So we can track the origin of the instantation to the macro definition, but
> then we don't show where the macro is invoked from, which is shown without
> -ftrack-macro-expansion. I think it should show both, like clang does

Agreed.

> Notice that in my ideal output, I also fixed the location given for the first
> instantation to point to "set" (1:19) and not to the end of the line
> (1:24).

Agreed again. I suspect this is related to our (ab)use of the global
input_location instead of relying on the precise location of the tokens
we are dealing with.  So I guess it'll take some iterations to generally
get this right, as you know already.
Comment 5 Manuel López-Ibáñez 2011-10-20 09:11:42 UTC
(In reply to comment #4)
> 
> Agreed again. I suspect this is related to our (ab)use of the global
> input_location instead of relying on the precise location of the tokens
> we are dealing with.  So I guess it'll take some iterations to generally
> get this right, as you know already.

Indeed. I must say it is superb that the infrastructure is there already, once this is a bit more stable, so many new things are possible. You should put a big item in http://gcc.gnu.org/gcc-4.7/changes.html, and some announcement in "News":

"Diagnostics in C++ have been significantly improved for 4.7: (1) The reasons for overload and lookup failure are now detailed described (thanks to the work of Nathan Froyd) (2) GCC is able to track macro expansions to provide more accurate locations in diagnostics (thanks to the work of Dodji Seketeli), and (3) Several hundreds of bugs related to diagnostics have been fixed for 4.7 (thanks to the work of Paolo Carlini and other contributors)."