]> granicus.if.org Git - clang/commitdiff
Avoid crash if default argument parsed with errors.
authorSerge Pavlov <sepavloff@gmail.com>
Tue, 22 Jul 2014 01:54:49 +0000 (01:54 +0000)
committerSerge Pavlov <sepavloff@gmail.com>
Tue, 22 Jul 2014 01:54:49 +0000 (01:54 +0000)
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

include/clang/Sema/Sema.h
lib/Parse/ParseCXXInlineMethods.cpp
lib/Parse/ParseDecl.cpp
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/default1.cpp

index 83488d0a6a615716a7bf8a118227feaea2136c07..8dba089924cce62298f0cef51a1fe43e2b4b9548 100644 (file)
@@ -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);
 
index 310e2b4cd8a9c4e5c4349e38dbcc09f5a16071cf..30a9120a5106435942306531189b06f86c5aa447 100644 (file)
@@ -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
index 74df162b0b3c2e39917469394d5768288e6028a0..62d43768bff414969a3a34c643e6fdc65ca41773 100644 (file)
@@ -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
index a0534ff31f63a27fa59589657ab299bdfb203180..c5cd83da59d61d42bcf702b0b732e05dfcaa6ce0 100644 (file)
@@ -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
index b661776b6ef589db0f4c4f2cacbb2582be295b45..23466fac62aaaaaee25237a617eabf2499dc6043 100644 (file)
@@ -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);