[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