[cfe-commits] [PATCH] PR10053 Improved two-stage lookup diagnostic

Richard Smith richard at metafoo.co.uk
Sun Jun 5 10:31:17 PDT 2011


Hi again,

On Sun, June 5, 2011 04:16, Douglas Gregor wrote:
> On Jun 4, 2011, at 1:37 PM, Richard Smith wrote:
>> The attached patch improves our error recovery when handling code which
>> some versions of gcc incorrectly accept, due to an incomplete
>> implementation of two-stage name lookup.
>>
>> This example from the compatibility section on the www:
>>
>>
>> template <typename T> T Squared(T x) { return Multiply(x, x); }
>>
>>
>> int Multiply(int x, int y) { return x * y; }
>>
>>
>> int main() { Squared(5);
>> }
>>
>>
>> Now produces the following diagnostics:
>>
>>
>> my_file.cpp:2:10: error: use of undeclared identifier 'Multiply'
>> return Multiply(x, x); ^
>> my_file.cpp:10:3: note: in instantiation of function template
>> specialization 'Squared<int>' requested here Squared(5);
>> ^
>> my_file.cpp:5:5: note: viable function not candidate: declared after
>> template was defined and not in an associated namespace int Multiply(int
>> x, int y) { ^
>
> The code looks good, but I think the diagnostic wording could be improved
> considerably. The error message should say what the problem is, and the
> note should suggest the solution. For example:
>
> error: call to function 'Multiply' that is neither visible in the
> template definition nor found by argument dependent lookup
>
> note: 'Multiply' should be declared prior to the call site or in the
> namespace of one of its arguments

The attached, revised patch produces this in the case where there are no
associated namespaces:

  my_file.cpp:2:10: error: call to function 'Multiply' that is neither
visible in the template definition nor found by argument dependent
lookup
    return Multiply(x, x);
           ^
  my_file.cpp:10:3: note: in instantiation of function template
specialization 'Squared<int>' requested here
    Squared(5);
    ^
  my_file.cpp:5:5: note: 'Multiply' should be declared prior to the call site
  int Multiply(int x, int y) {
      ^

In the case where there is a single associated namespace (excluding those
within namespace std), we produce this:

  my_file2.cpp:5:13: error: call to function 'operator<<' that is neither
visible in the template definition nor found by argument dependent
lookup
    std::cout << value << "\n";
              ^
  my_file2.cpp:17:3: note: in instantiation of function template
specialization 'Dump<ns::Data>' requested here
    Dump(ns::Data());
    ^
  my_file2.cpp:12:15: note: 'operator<<' should be declared prior to the
call site or in namespace 'ns'
  std::ostream& operator<<(std::ostream& out, ns::Data data) {
                ^

Finally, if there are multiple associated namespaces for the call, we
produce a slightly tweaked version of the diagnostic you suggested:

  my_file3.cpp:5:10: error: call to function 'operator!' that is neither
visible in the template definition nor found by argument dependent
lookup
    return !value;
           ^
  my_file3.cpp:18:3: note: in instantiation of function template
specialization 'Negate<ns2::S<ns::Data> >' requested here
    Negate(ns2::S<ns::Data>());
    ^
  my_file3.cpp:15:18: note: 'operator!' should be declared prior to the
call site or in an associated namespace of one of its arguments
  ns2::S<ns::Data> operator!(ns2::S<ns::Data>);
                   ^

>> This patch only diagnoses normal unqualified names; diagnostics for
>> names with scope specifiers and for overloaded operators are not
>> similarly improved.

I've extended the patch to also cover overloaded operators. We don't fully
recover in that case, but we do produce the improved diagnostic.

Comments?

Thanks,
Richard





More information about the cfe-commits mailing list