diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index ae7917d6772d..48113eb6ba5f 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/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/clang/test/Analysis/cfg-rich-constructors.cpp b/clang/test/Analysis/cfg-rich-constructors.cpp index ca74b7c93cf7..31c306bbfe9c 100644 --- a/clang/test/Analysis/cfg-rich-constructors.cpp +++ b/clang/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