summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerge Pavlov <sepavloff@gmail.com>2014-07-22 01:54:49 +0000
committerSerge Pavlov <sepavloff@gmail.com>2014-07-22 01:54:49 +0000
commit9115f7255f489610de3cd3bb9e1a1aef66e38ae9 (patch)
tree354d2a34c36648eb31479dfaf2f3c2d601ce233e
parente6de71dffb8ce404e22505f0e80015137437fde9 (diff)
Avoid crash if default argument parsed with errors.
If function parameters have default values, and that of the second parameter is parsed with errors, function declaration would have a parameter without default value that follows a parameter with that. Such declaration breaks logic of selecting overloaded function. As a solution, put opaque object as default value in such case. This patch fixes PR20055. Differential Revision: http://reviews.llvm.org/D4378 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@213594 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Sema/Sema.h2
-rw-r--r--lib/Parse/ParseCXXInlineMethods.cpp3
-rw-r--r--lib/Parse/ParseDecl.cpp4
-rw-r--r--lib/Sema/SemaDeclCXX.cpp5
-rw-r--r--test/SemaCXX/default1.cpp3
5 files changed, 12 insertions, 5 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 83488d0a6a..8dba089924 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1625,7 +1625,7 @@ public:
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);
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index 310e2b4cd8..30a9120a51 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -337,7 +337,8 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
} 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
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 74df162b0b..62d43768bf 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -5436,7 +5436,7 @@ void Parser::ParseParameterDeclarationClause(
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 @@ void Parser::ParseParameterDeclarationClause(
} 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
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index a0534ff31f..c5cd83da59 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -344,13 +344,16 @@ void Sema::ActOnParamUnparsedDefaultArgument(Decl *param,
/// 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<ParmVarDecl>(param);
Param->setInvalidDecl();
UnparsedDefaultArgLocs.erase(Param);
+ Param->setDefaultArg(new(Context)
+ OpaqueValueExpr(EqualLoc, Param->getType(), VK_RValue));
}
/// CheckExtraCXXDefaultArguments - Check for any extra default
diff --git a/test/SemaCXX/default1.cpp b/test/SemaCXX/default1.cpp
index b661776b6e..23466fac62 100644
--- a/test/SemaCXX/default1.cpp
+++ b/test/SemaCXX/default1.cpp
@@ -62,3 +62,6 @@ int i2() {
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);