From c4a3768bd227fb4433e32e17bab699eabf7cc793 Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Sat, 4 Jan 2014 01:57:42 +0000 Subject: [PATCH] Ignore qualified templated functions for -Winfinite-recursion. This treats functions like Foo<5>::run() the same way as run<5>() for this warning. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@198470 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/AnalysisBasedWarnings.cpp | 12 ++++++++++++ test/SemaCXX/warn-infinite-recursion.cpp | 23 +++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index 57c0ac311c..72f8ee1d29 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -116,6 +116,18 @@ static void checkForFunctionCall(Sema &S, const FunctionDecl *FD, const CallExpr *CE = dyn_cast(I->getAs()->getStmt()); if (CE && CE->getCalleeDecl() && CE->getCalleeDecl()->getCanonicalDecl() == FD) { + + // Skip function calls which are qualified with a templated class. + if (const DeclRefExpr *DRE = dyn_cast( + CE->getCallee()->IgnoreParenImpCasts())) { + if (NestedNameSpecifier *NNS = DRE->getQualifier()) { + if (NNS->getKind() == NestedNameSpecifier::TypeSpec && + isa(NNS->getAsType())) { + continue; + } + } + } + if (const CXXMemberCallExpr *MCE = dyn_cast(CE)) { if (isa(MCE->getImplicitObjectArgument()) || !MCE->getMethodDecl()->isVirtual()) { diff --git a/test/SemaCXX/warn-infinite-recursion.cpp b/test/SemaCXX/warn-infinite-recursion.cpp index 088d4ba3de..e1b7c5412e 100644 --- a/test/SemaCXX/warn-infinite-recursion.cpp +++ b/test/SemaCXX/warn-infinite-recursion.cpp @@ -127,3 +127,26 @@ int DoStuff() { return 0; } int stuff = DoStuff<0, 1>(); + +template +struct Wrapper { + static int run() { + // Similar to the above, Wrapper<0>::run() will discard the if statement. + if (x == 1) + return 0; + return Wrapper::run(); + } + static int run2() { // expected-warning{{call itself}} + return run2(); + } +}; + +template +int test_wrapper() { + if (x != 0) + return Wrapper::run() + + Wrapper::run2(); // expected-note{{instantiation}} + return 0; +} + +int wrapper_sum = test_wrapper<2>(); // expected-note{{instantiation}} -- 2.40.0