From e9188a90955075de9154ad4e8b50845cb7f132c0 Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Tue, 14 Jun 2016 02:55:56 +0000 Subject: [PATCH] Detect recursive default argument definition If definition of default function argument uses itself, clang crashed, because corresponding function parameter is not associated with the default argument yet. With this fix clang emits appropriate error message. This change fixes PR28105. Differential Revision: http://reviews.llvm.org/D21301 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@272623 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 1 + lib/Sema/SemaExpr.cpp | 7 +++++++ test/SemaCXX/default2.cpp | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index a607690a14..9992c77989 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -3107,6 +3107,7 @@ def err_use_of_default_argument_to_function_declared_later : Error< "use of default argument to function %0 that is declared later in class %1">; def note_default_argument_declared_here : Note< "default argument declared here">; +def err_recursive_default_argument : Error<"recursive evaluation of default argument">; def ext_param_promoted_not_compatible_with_prototype : ExtWarn< "%diff{promoted type $ of K&R function parameter is not compatible with the " diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index f766091e54..f617db9151 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4566,6 +4566,13 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, } } + // If the default argument expression is not set yet, we are building it now. + if (!Param->hasInit()) { + Diag(Param->getLocStart(), diag::err_recursive_default_argument) << FD; + Param->setInvalidDecl(); + return ExprError(); + } + // If the default expression creates temporaries, we need to // push them to the current stack of expression temporaries so they'll // be properly destroyed. diff --git a/test/SemaCXX/default2.cpp b/test/SemaCXX/default2.cpp index c4d40b4280..8f77f30057 100644 --- a/test/SemaCXX/default2.cpp +++ b/test/SemaCXX/default2.cpp @@ -128,3 +128,7 @@ S<1> s; template struct T {}; // expected-error-re {{use of undeclared identifier 'I2'{{$}}}} T<0, 1> t; + +struct PR28105 { + PR28105 (int = 0, int = 0, PR28105 = 0); // expected-error{{recursive evaluation of default argument}} +}; -- 2.40.0