From c8b31d0d0079871780d1bb65e4c5d25e5a391474 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Wed, 29 Aug 2018 21:50:52 +0000 Subject: [PATCH] [CFG] [analyzer] Disable argument construction contexts for variadic functions. The analyzer doesn't make use of them anyway and they seem to have pretty weird AST from time to time, so let's just skip them for now. Fixes pr37769. Differential Revision: https://reviews.llvm.org/D50824 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@340975 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/CFG.cpp | 9 +++++++-- test/Analysis/cfg-rich-constructors.cpp | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index ae7917d677..48113eb6ba 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -2421,8 +2421,6 @@ CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) { if (!boundType.isNull()) calleeType = boundType; } - findConstructionContextsForArguments(C); - // If this is a call to a no-return function, this stops the block here. bool NoReturn = getFunctionExtInfo(*calleeType).getNoReturn(); @@ -2439,6 +2437,13 @@ CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) { bool OmitArguments = false; if (FunctionDecl *FD = C->getDirectCallee()) { + // TODO: Support construction contexts for variadic function arguments. + // These are a bit problematic and not very useful because passing + // C++ objects as C-style variadic arguments doesn't work in general + // (see [expr.call]). + if (!FD->isVariadic()) + findConstructionContextsForArguments(C); + if (FD->isNoReturn() || C->isBuiltinAssumeFalse(*Context)) NoReturn = true; if (FD->hasAttr()) diff --git a/test/Analysis/cfg-rich-constructors.cpp b/test/Analysis/cfg-rich-constructors.cpp index ca74b7c93c..31c306bbfe 100644 --- a/test/Analysis/cfg-rich-constructors.cpp +++ b/test/Analysis/cfg-rich-constructors.cpp @@ -1028,3 +1028,18 @@ void testOperators() { C(1) + C(2); } } // namespace operators + +namespace variadic_function_arguments { +class C { + public: + C(int); +}; + +int variadic(...); + +// This code is quite exotic, so let's not test the CFG for it, +// but only make sure we don't crash. +void testCrashOnVariadicArgument() { + C c(variadic(0 ? c : 0)); // no-crash +} +} // namespace variadic_function_arguments -- 2.50.1