Skip to content
Snippets Groups Projects
Commit e9188a90 authored by Serge Pavlov's avatar Serge Pavlov
Browse files

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
parent b1d69700
No related branches found
No related tags found
No related merge requests found
...@@ -3107,6 +3107,7 @@ def err_use_of_default_argument_to_function_declared_later : Error< ...@@ -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">; "use of default argument to function %0 that is declared later in class %1">;
def note_default_argument_declared_here : Note< def note_default_argument_declared_here : Note<
"default argument declared here">; "default argument declared here">;
def err_recursive_default_argument : Error<"recursive evaluation of default argument">;
def ext_param_promoted_not_compatible_with_prototype : ExtWarn< def ext_param_promoted_not_compatible_with_prototype : ExtWarn<
"%diff{promoted type $ of K&R function parameter is not compatible with the " "%diff{promoted type $ of K&R function parameter is not compatible with the "
......
...@@ -4566,6 +4566,13 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, ...@@ -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 // If the default expression creates temporaries, we need to
// push them to the current stack of expression temporaries so they'll // push them to the current stack of expression temporaries so they'll
// be properly destroyed. // be properly destroyed.
......
...@@ -128,3 +128,7 @@ S<1> s; ...@@ -128,3 +128,7 @@ S<1> s;
template <int I1 = I2, int I2 = 1> struct T {}; // expected-error-re {{use of undeclared identifier 'I2'{{$}}}} template <int I1 = I2, int I2 = 1> struct T {}; // expected-error-re {{use of undeclared identifier 'I2'{{$}}}}
T<0, 1> t; T<0, 1> t;
struct PR28105 {
PR28105 (int = 0, int = 0, PR28105 = 0); // expected-error{{recursive evaluation of default argument}}
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment