Index: cfe/trunk/include/clang/Sema/Sema.h =================================================================== --- cfe/trunk/include/clang/Sema/Sema.h +++ cfe/trunk/include/clang/Sema/Sema.h @@ -1625,7 +1625,7 @@ void ActOnParamUnparsedDefaultArgument(Decl *param, SourceLocation EqualLoc, SourceLocation ArgLoc); - void ActOnParamDefaultArgumentError(Decl *param); + void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc); bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, SourceLocation EqualLoc); Index: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp =================================================================== --- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp +++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp @@ -337,7 +337,8 @@ } else DefArgResult = ParseAssignmentExpression(); if (DefArgResult.isInvalid()) - Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param); + Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param, + EqualLoc); else { if (!TryConsumeToken(tok::cxx_defaultarg_end)) { // The last two tokens are the terminator and the saved value of Index: cfe/trunk/lib/Parse/ParseDecl.cpp =================================================================== --- cfe/trunk/lib/Parse/ParseDecl.cpp +++ cfe/trunk/lib/Parse/ParseDecl.cpp @@ -5436,7 +5436,7 @@ if (!ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument)) { delete DefArgToks; DefArgToks = nullptr; - Actions.ActOnParamDefaultArgumentError(Param); + Actions.ActOnParamDefaultArgumentError(Param, EqualLoc); } else { // Mark the end of the default argument so that we know when to // stop when we parse it later on. @@ -5465,7 +5465,7 @@ } else DefArgResult = ParseAssignmentExpression(); if (DefArgResult.isInvalid()) { - Actions.ActOnParamDefaultArgumentError(Param); + Actions.ActOnParamDefaultArgumentError(Param, EqualLoc); SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch); } else { // Inform the actions module about the default argument Index: cfe/trunk/lib/Sema/SemaDeclCXX.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp @@ -344,13 +344,16 @@ /// ActOnParamDefaultArgumentError - Parsing or semantic analysis of /// the default argument for the parameter param failed. -void Sema::ActOnParamDefaultArgumentError(Decl *param) { +void Sema::ActOnParamDefaultArgumentError(Decl *param, + SourceLocation EqualLoc) { if (!param) return; ParmVarDecl *Param = cast(param); Param->setInvalidDecl(); UnparsedDefaultArgLocs.erase(Param); + Param->setDefaultArg(new(Context) + OpaqueValueExpr(EqualLoc, Param->getType(), VK_RValue)); } /// CheckExtraCXXDefaultArguments - Check for any extra default Index: cfe/trunk/test/SemaCXX/default1.cpp =================================================================== --- cfe/trunk/test/SemaCXX/default1.cpp +++ cfe/trunk/test/SemaCXX/default1.cpp @@ -62,3 +62,6 @@ j(2, 3); // expected-error{{too many arguments to function call, expected at most single argument 'f', have 2}} } } + +int pr20055_f(int x = 0, int y = UNDEFINED); // expected-error{{use of undeclared identifier}} +int pr20055_v = pr20055_f(0);