diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/unused-using-decls.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/unused-using-decls.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/misc/unused-using-decls.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/unused-using-decls.cpp @@ -210,3 +210,14 @@ // We used to report Q unsued, because we only checked the first template // argument. Bar *bar; + +namespace internal { + struct S {}; + int operator+(S s1, S s2) { return 0; }; +} + +// Make sure this statement is not reported as unused. +using internal::operator+; +using internal::S; + +int j() { return S() + S(); } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -63,8 +63,10 @@ // being used. if (FoundDecl != Fn && S.DiagnoseUseOfDecl(Fn, Loc)) return ExprError(); - DeclRefExpr *DRE = new (S.Context) - DeclRefExpr(S.Context, Fn, false, Fn->getType(), VK_LValue, Loc, LocInfo); + DeclRefExpr *DRE = + DeclRefExpr::Create(S.Context, Fn->getQualifierLoc(), Loc, Fn, false, + Loc, Fn->getType(), VK_LValue, + FoundDecl); if (HadMultipleCandidates) DRE->setHadMultipleCandidates(true); diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -4675,6 +4675,9 @@ EXPECT_TRUE(notMatches( "namespace a { void f(); } using a::f; void g() { a::f(); }", declRefExpr(throughUsingDecl(anything())))); + EXPECT_TRUE(matches( + "struct S {}; namespace a { int operator+(S s1, S s2) { return 0; }; } using a::operator+; int g() { S a, b; return a + b; }", + declRefExpr(throughUsingDecl(anything())))); } TEST(SingleDecl, IsSingleDecl) {