Author: szelethus Date: Fri May 25 06:18:38 2018 New Revision: 333275 URL: http://llvm.org/viewvc/llvm-project?rev=333275&view=rev Log: [analyzer] Added template argument lists to the Pathdiagnostic output
Because template parameter lists were not displayed in the plist output, it was difficult to decide in some cases whether a given checker found a true or a false positive. This patch aims to correct this. Differential Revision: https://reviews.llvm.org/D46933 Added: cfe/trunk/test/Analysis/plist-diagnostics-template-function.cpp cfe/trunk/test/Analysis/plist-diagnostics-template-record.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp?rev=333275&r1=333274&r2=333275&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp Fri May 25 06:18:38 2018 @@ -16,6 +16,7 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/OperationKinds.h" @@ -1000,11 +1001,49 @@ void PathDiagnosticCallPiece::setCallee( CalleeCtx->getAnalysisDeclContext()->isBodyAutosynthesized()); } +static void describeTemplateParameters(raw_ostream &Out, + const ArrayRef<TemplateArgument> TAList, + const LangOptions &LO, + StringRef Prefix = StringRef(), + StringRef Postfix = StringRef()); + +static void describeTemplateParameter(raw_ostream &Out, + const TemplateArgument &TArg, + const LangOptions &LO) { + + if (TArg.getKind() == TemplateArgument::ArgKind::Pack) { + describeTemplateParameters(Out, TArg.getPackAsArray(), LO); + } else { + TArg.print(PrintingPolicy(LO), Out); + } +} + +static void describeTemplateParameters(raw_ostream &Out, + const ArrayRef<TemplateArgument> TAList, + const LangOptions &LO, + StringRef Prefix, StringRef Postfix) { + if (TAList.empty()) + return; + + Out << Prefix; + for (int I = 0, Last = TAList.size() - 1; I != Last; ++I) { + describeTemplateParameter(Out, TAList[I], LO); + Out << ", "; + } + describeTemplateParameter(Out, TAList[TAList.size() - 1], LO); + Out << Postfix; +} + static void describeClass(raw_ostream &Out, const CXXRecordDecl *D, StringRef Prefix = StringRef()) { if (!D->getIdentifier()) return; - Out << Prefix << '\'' << *D << '\''; + Out << Prefix << '\'' << *D; + if (const auto T = dyn_cast<ClassTemplateSpecializationDecl>(D)) + describeTemplateParameters(Out, T->getTemplateArgs().asArray(), + D->getASTContext().getLangOpts(), "<", ">"); + + Out << '\''; } static bool describeCodeDecl(raw_ostream &Out, const Decl *D, @@ -1062,7 +1101,16 @@ static bool describeCodeDecl(raw_ostream return true; } - Out << Prefix << '\'' << cast<NamedDecl>(*D) << '\''; + Out << Prefix << '\'' << cast<NamedDecl>(*D); + + // Adding template parameters. + if (const auto FD = dyn_cast<FunctionDecl>(D)) + if (const TemplateArgumentList *TAList = + FD->getTemplateSpecializationArgs()) + describeTemplateParameters(Out, TAList->asArray(), + FD->getASTContext().getLangOpts(), "<", ">"); + + Out << '\''; return true; } Added: cfe/trunk/test/Analysis/plist-diagnostics-template-function.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/plist-diagnostics-template-function.cpp?rev=333275&view=auto ============================================================================== --- cfe/trunk/test/Analysis/plist-diagnostics-template-function.cpp (added) +++ cfe/trunk/test/Analysis/plist-diagnostics-template-function.cpp Fri May 25 06:18:38 2018 @@ -0,0 +1,41 @@ +// RUN: %clang_analyze_cc1 -analyzer-output=plist -o %t.plist -std=c++11 -analyzer-checker=core %s +// RUN: FileCheck --input-file=%t.plist %s + +bool ret(); + +template <class T> +void f(int i) { + if (ret()) + i = i / (i - 5); +} + +template <> +void f<int>(int i) { + if (ret()) + i = i / (i - 5); +} + +template <int N = 0> +void defaultTemplateParameterFunction(int i) { + if (ret()) + int a = 10 / i; +} + +template <typename... Args> +void variadicTemplateFunction(int i) { + if (ret()) + int a = 10 / i; +} + +int main() { + f<int>(5); + f<float>(5); + defaultTemplateParameterFunction<>(0); + variadicTemplateFunction<char, float, double, int *>(0); +} + +// CHECK: <string>Calling 'f<float>'</string> +// CHECK: <string>Calling 'f<int>'</string> +// CHECK: <string>Calling 'defaultTemplateParameterFunction<0>'</string> +// CHECK: <string>Calling 'variadicTemplateFunction<char, float, double, int *>'</string> + Added: cfe/trunk/test/Analysis/plist-diagnostics-template-record.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/plist-diagnostics-template-record.cpp?rev=333275&view=auto ============================================================================== --- cfe/trunk/test/Analysis/plist-diagnostics-template-record.cpp (added) +++ cfe/trunk/test/Analysis/plist-diagnostics-template-record.cpp Fri May 25 06:18:38 2018 @@ -0,0 +1,42 @@ +// RUN: %clang_analyze_cc1 -analyzer-output=plist -o %t.plist -std=c++11 -analyzer-checker=core %s +// RUN: FileCheck --input-file=%t.plist %s + +bool ret(); + +template <class A, class B, class C, int N> +struct DivByZero { + int i; + DivByZero(bool b) { + if (ret()) + i = 50 / (b - 1); + } +}; + +template <class B, class C, int N> +struct DivByZero<char, B, C, N> { + int i; + DivByZero(bool b) { + if (ret()) + i = 50 / (b - 1); + } +}; + +template <typename... Args> +struct DivByZeroVariadic { + int i; + DivByZeroVariadic(bool b) { + if (ret()) + i = 50 / (b - 1); + } +}; + +int main() { + DivByZero<int, float, double, 0> a(1); + DivByZero<char, float, double, 0> a2(1); + DivByZeroVariadic<char, float, double, decltype(nullptr)> a3(1); +} + +// CHECK: <string>Calling constructor for 'DivByZero<int, float, double, 0>'</string> +// CHECK: <string>Calling constructor for 'DivByZero<char, float, double, 0>'</string> +// CHECK: <string>Calling constructor for 'DivByZeroVariadic<char, float, double, nullptr_t>'</string> + _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits