summaryrefslogtreecommitdiff
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)
downloadclang-9115f7255f489610de3cd3bb9e1a1aef66e38ae9.tar.gz
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);