summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-08-11 23:30:23 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-08-11 23:30:23 +0000
commit36ee9fb219579e8bcac3032a042b3bddd98b3938 (patch)
tree335b274df5e87700dee249b936bfaa6e644dc351 /clang/lib/Parse/ParseDecl.cpp
parent76502d84179e52d6ab1c657b4baf0e92ee27f912 (diff)
downloadbcm5719-llvm-36ee9fb219579e8bcac3032a042b3bddd98b3938.tar.gz
bcm5719-llvm-36ee9fb219579e8bcac3032a042b3bddd98b3938.zip
Reject varargs '...' in function prototype if there are more parameters after
it. Diagnose with recovery if it appears after a function parameter that was obviously supposed to be a parameter pack. Otherwise, warn if it immediately follows a function parameter pack, because the user most likely didn't intend to write a parameter pack followed by a C-style varargs ellipsis. This warning can be syntactically disabled by using ", ..." instead of "...". llvm-svn: 215408
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp41
1 files changed, 36 insertions, 5 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index b4713659b4f..76f1e084423 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5426,6 +5426,15 @@ void Parser::ParseParameterDeclarationClause(
// Otherwise, we have something. Add it and let semantic analysis try
// to grok it and add the result to the ParamInfo we are building.
+ // Last chance to recover from a misplaced ellipsis in an attempted
+ // parameter pack declaration.
+ if (Tok.is(tok::ellipsis) &&
+ (NextToken().isNot(tok::r_paren) ||
+ (!ParmDeclarator.getEllipsisLoc().isValid() &&
+ !Actions.isUnexpandedParameterPackPermitted())) &&
+ Actions.containsUnexpandedParameterPacks(ParmDeclarator))
+ DiagnoseMisplacedEllipsisInDeclarator(ConsumeToken(), ParmDeclarator);
+
// Inform the actions module about the parameter declarator, so it gets
// added to the current scope.
Decl *Param = Actions.ActOnParamDeclarator(getCurScope(),
@@ -5492,12 +5501,34 @@ void Parser::ParseParameterDeclarationClause(
Param, DefArgToks));
}
- if (TryConsumeToken(tok::ellipsis, EllipsisLoc) &&
- !getLangOpts().CPlusPlus) {
- // We have ellipsis without a preceding ',', which is ill-formed
- // in C. Complain and provide the fix.
- Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
+ if (TryConsumeToken(tok::ellipsis, EllipsisLoc)) {
+ if (!getLangOpts().CPlusPlus) {
+ // We have ellipsis without a preceding ',', which is ill-formed
+ // in C. Complain and provide the fix.
+ Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
+ << FixItHint::CreateInsertion(EllipsisLoc, ", ");
+ } else if (ParmDeclarator.getEllipsisLoc().isValid() ||
+ Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {
+ // It looks like this was supposed to be a parameter pack. Warn and
+ // point out where the ellipsis should have gone.
+ SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();
+ Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
+ << ParmEllipsis.isValid() << ParmEllipsis;
+ if (ParmEllipsis.isValid()) {
+ Diag(ParmEllipsis,
+ diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
+ } else {
+ Diag(ParmDeclarator.getIdentifierLoc(),
+ diag::note_misplaced_ellipsis_vararg_add_ellipsis)
+ << FixItHint::CreateInsertion(ParmDeclarator.getIdentifierLoc(),
+ "...")
+ << !ParmDeclarator.hasName();
+ }
+ Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
<< FixItHint::CreateInsertion(EllipsisLoc, ", ");
+ }
+
+ // We can't have any more parameters after an ellipsis.
break;
}
OpenPOWER on IntegriCloud