[PATCH] Avoid crash if default argument parsed with errors.

Richard Smith richard at metafoo.co.uk
Tue Jul 8 13:09:02 PDT 2014


On Thu, Jul 3, 2014 at 11:43 AM, Serge Pavlov <sepavloff at gmail.com> wrote:

> 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, erase default value of all parameters that precedes
> the erroneous parameter.
>
> This patch fixes PR20055.
>
> http://reviews.llvm.org/D4378
>
> Files:
>   lib/Sema/SemaDecl.cpp
>   test/SemaCXX/default1.cpp
>
> Index: lib/Sema/SemaDecl.cpp
> ===================================================================
> --- lib/Sema/SemaDecl.cpp
> +++ lib/Sema/SemaDecl.cpp
> @@ -7074,15 +7074,25 @@
>      // single void argument.
>      // We let through "const void" here because Sema::GetTypeForDeclarator
>      // already checks for that case.
> +    ParmVarDecl *Prev = nullptr;
>      if (FTIHasNonVoidParameters(FTI) && FTI.Params[0].Param) {
>        for (unsigned i = 0, e = FTI.NumParams; i != e; ++i) {
>          ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[i].Param);
>          assert(Param->getDeclContext() != NewFD && "Was set before ?");
>          Param->setDeclContext(NewFD);
>          Params.push_back(Param);
>
> -        if (Param->isInvalidDecl())
> +        if (Param->isInvalidDecl()) {
>            NewFD->setInvalidDecl();
> +          if (!Param->hasDefaultArg() && Prev && Prev->hasDefaultArg()) {
> +            for (unsigned j = i; j != 0; --j) {
> +              ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[j -
> 1].Param);
> +              if (!Param->hasDefaultArg()) break;
> +              Param->setDefaultArg(nullptr);
> +            }
> +          }
> +        }
> +        Prev = Param;
>        }
>      }
>
> Index: test/SemaCXX/default1.cpp
> ===================================================================
> --- test/SemaCXX/default1.cpp
> +++ test/SemaCXX/default1.cpp
> @@ -62,3 +62,7 @@
>      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}} \
> +                                             // expected-note{{candidate
> function not viable}}
> +int pr20055_v = pr20055_f(0); // expected-error{{no matching function for
> call}}


This error recovery doesn't seem ideal. Perhaps instead we could create an
OpaqueValueExpr of the appropriate type to represent a default argument
that couldn't be parsed?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140708/c8942701/attachment.html>


More information about the cfe-commits mailing list