EricWF created this revision. Previously Clang was not considering operator declarations that occur at function scope. This is incorrect according to [over.match.oper]p3
> The set of non-member candidates is the result of the unqualified lookup of > operator@ in the context of the expression according to the usual rules for > name lookup in unqualified function calls. This patch fixes operator name lookup to consider block scope declarations. I think there might be existing open bugs for this but I can't find them. https://reviews.llvm.org/D35297 Files: lib/Sema/SemaLookup.cpp test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp Index: test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp =================================================================== --- test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp +++ test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp @@ -2,6 +2,21 @@ namespace bullet2 { +// The set of non-member candidates is the result of the unqualified lookup of +// operator@ in the context of the expression according to the usual rules for +// name lookup in unqualified function calls. + +// Test that local extern declarations are allowed. +struct A {}; +void test_local_lookup() { + A a; + +a; // expected-error {{invalid argument type 'bullet2::A' to unary expression}} + a + a; // expected-error {{invalid operands to binary expression ('bullet2::A' and 'bullet2::A')}} + void operator+(A); + void operator+(A, A); + +a; // OK + a + a; +} // For non-member candidates, if no operand has a class type, only those // non-member functions that have a matching enumeration parameter are // candidates. Index: lib/Sema/SemaLookup.cpp =================================================================== --- lib/Sema/SemaLookup.cpp +++ lib/Sema/SemaLookup.cpp @@ -226,7 +226,7 @@ // Operator lookup is its own crazy thing; it is not the same // as (e.g.) looking up an operator name for redeclaration. assert(!Redeclaration && "cannot do redeclaration operator lookup"); - IDNS = Decl::IDNS_NonMemberOperator; + IDNS = Decl::IDNS_NonMemberOperator | Decl::IDNS_LocalExtern; break; case Sema::LookupTagName:
Index: test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp =================================================================== --- test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp +++ test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp @@ -2,6 +2,21 @@ namespace bullet2 { +// The set of non-member candidates is the result of the unqualified lookup of +// operator@ in the context of the expression according to the usual rules for +// name lookup in unqualified function calls. + +// Test that local extern declarations are allowed. +struct A {}; +void test_local_lookup() { + A a; + +a; // expected-error {{invalid argument type 'bullet2::A' to unary expression}} + a + a; // expected-error {{invalid operands to binary expression ('bullet2::A' and 'bullet2::A')}} + void operator+(A); + void operator+(A, A); + +a; // OK + a + a; +} // For non-member candidates, if no operand has a class type, only those // non-member functions that have a matching enumeration parameter are // candidates. Index: lib/Sema/SemaLookup.cpp =================================================================== --- lib/Sema/SemaLookup.cpp +++ lib/Sema/SemaLookup.cpp @@ -226,7 +226,7 @@ // Operator lookup is its own crazy thing; it is not the same // as (e.g.) looking up an operator name for redeclaration. assert(!Redeclaration && "cannot do redeclaration operator lookup"); - IDNS = Decl::IDNS_NonMemberOperator; + IDNS = Decl::IDNS_NonMemberOperator | Decl::IDNS_LocalExtern; break; case Sema::LookupTagName:
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits