Fix crash if base specifier parsing hits an invalid type annotation.
Also change type annotation representation from ParsedType to TypeResult
to make it clearer to consumers that they can represent invalid types.
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 95706fb..e60d1f6 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3217,16 +3217,12 @@
if (Next.is(tok::annot_typename)) {
DS.getTypeSpecScope() = SS;
ConsumeAnnotationToken(); // The C++ scope.
- if (Tok.getAnnotationValue()) {
- ParsedType T = getTypeAnnotation(Tok);
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename,
- Tok.getAnnotationEndLoc(),
- PrevSpec, DiagID, T, Policy);
- if (isInvalid)
- break;
- }
- else
- DS.SetTypeSpecError();
+ TypeResult T = getTypeAnnotation(Tok);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename,
+ Tok.getAnnotationEndLoc(),
+ PrevSpec, DiagID, T, Policy);
+ if (isInvalid)
+ break;
DS.SetRangeEnd(Tok.getAnnotationEndLoc());
ConsumeAnnotationToken(); // The typename
}
@@ -3294,13 +3290,9 @@
if (DS.hasTypeSpecifier() && DS.hasTagDefinition())
goto DoneWithDeclSpec;
- if (Tok.getAnnotationValue()) {
- ParsedType T = getTypeAnnotation(Tok);
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
- DiagID, T, Policy);
- } else
- DS.SetTypeSpecError();
-
+ TypeResult T = getTypeAnnotation(Tok);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
+ DiagID, T, Policy);
if (isInvalid)
break;
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 98918ef..7106323 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1151,13 +1151,10 @@
AnnotateTemplateIdTokenAsType(SS, /*IsClassName*/true);
assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
- ParsedType Type = getTypeAnnotation(Tok);
+ TypeResult Type = getTypeAnnotation(Tok);
EndLocation = Tok.getAnnotationEndLoc();
ConsumeAnnotationToken();
-
- if (Type)
- return Type;
- return true;
+ return Type;
}
// Fall through to produce an error below.
@@ -1204,7 +1201,7 @@
// Retrieve the type from the annotation token, consume that token, and
// return.
EndLocation = Tok.getAnnotationEndLoc();
- ParsedType Type = getTypeAnnotation(Tok);
+ TypeResult Type = getTypeAnnotation(Tok);
ConsumeAnnotationToken();
return Type;
}
@@ -3510,7 +3507,7 @@
// : declype(...)
DeclSpec DS(AttrFactory);
// : template_name<...>
- ParsedType TemplateTypeTy;
+ TypeResult TemplateTypeTy;
if (Tok.is(tok::identifier)) {
// Get the identifier. This may be a member name or a class name,
@@ -3532,8 +3529,6 @@
assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
TemplateTypeTy = getTypeAnnotation(Tok);
ConsumeAnnotationToken();
- if (!TemplateTypeTy)
- return true;
} else {
Diag(Tok, diag::err_expected_member_or_base_name);
return true;
@@ -3552,8 +3547,10 @@
SourceLocation EllipsisLoc;
TryConsumeToken(tok::ellipsis, EllipsisLoc);
+ if (TemplateTypeTy.isInvalid())
+ return true;
return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
- TemplateTypeTy, DS, IdLoc,
+ TemplateTypeTy.get(), DS, IdLoc,
InitList.get(), EllipsisLoc);
} else if(Tok.is(tok::l_paren)) {
BalancedDelimiterTracker T(*this, tok::l_paren);
@@ -3563,8 +3560,10 @@
ExprVector ArgExprs;
CommaLocsTy CommaLocs;
auto RunSignatureHelp = [&] {
+ if (TemplateTypeTy.isInvalid())
+ return QualType();
QualType PreferredType = Actions.ProduceCtorInitMemberSignatureHelp(
- getCurScope(), ConstructorDecl, SS, TemplateTypeTy, ArgExprs, II,
+ getCurScope(), ConstructorDecl, SS, TemplateTypeTy.get(), ArgExprs, II,
T.getOpenLocation());
CalledSignatureHelp = true;
return PreferredType;
@@ -3585,12 +3584,17 @@
SourceLocation EllipsisLoc;
TryConsumeToken(tok::ellipsis, EllipsisLoc);
+ if (TemplateTypeTy.isInvalid())
+ return true;
return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
- TemplateTypeTy, DS, IdLoc,
+ TemplateTypeTy.get(), DS, IdLoc,
T.getOpenLocation(), ArgExprs,
T.getCloseLocation(), EllipsisLoc);
}
+ if (TemplateTypeTy.isInvalid())
+ return true;
+
if (getLangOpts().CPlusPlus11)
return Diag(Tok, diag::err_expected_either) << tok::l_paren << tok::l_brace;
else
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 8059267..9a0f94a 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1455,7 +1455,7 @@
break;
case tok::annot_typename:
if (isStartOfObjCClassMessageMissingOpenBracket()) {
- ParsedType Type = getTypeAnnotation(Tok);
+ TypeResult Type = getTypeAnnotation(Tok);
// Fake up a Declarator to use with ActOnTypeName.
DeclSpec DS(AttrFactory);
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 4389c87..c5e895d 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -2147,12 +2147,8 @@
// type-name
case tok::annot_typename: {
- if (getTypeAnnotation(Tok))
- DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID,
- getTypeAnnotation(Tok), Policy);
- else
- DS.SetTypeSpecError();
-
+ DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID,
+ getTypeAnnotation(Tok), Policy);
DS.SetRangeEnd(Tok.getAnnotationEndLoc());
ConsumeAnnotationToken();
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index f0a2a48..10252b0 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -2978,7 +2978,7 @@
InMessageExpression)
return false;
- ParsedType Type;
+ TypeResult Type;
if (Tok.is(tok::annot_typename))
Type = getTypeAnnotation(Tok);
@@ -2988,7 +2988,8 @@
else
return false;
- if (!Type.get().isNull() && Type.get()->isObjCObjectOrInterfaceType()) {
+ // FIXME: Should not be querying properties of types from the parser.
+ if (Type.isUsable() && Type.get().get()->isObjCObjectOrInterfaceType()) {
const Token &AfterNext = GetLookAheadToken(2);
if (AfterNext.isOneOf(tok::colon, tok::r_square)) {
if (Tok.is(tok::identifier))
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index d383839..5025ea5 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -1321,7 +1321,7 @@
LAngleLoc, TemplateArgsPtr, RAngleLoc);
Tok.setKind(tok::annot_typename);
- setTypeAnnotation(Tok, Type.isInvalid() ? nullptr : Type.get());
+ setTypeAnnotation(Tok, Type);
if (SS.isNotEmpty())
Tok.setLocation(SS.getBeginLoc());
else if (TemplateKWLoc.isValid())
@@ -1398,7 +1398,7 @@
/*IsCtorOrDtorName*/ false, IsClassName);
// Create the new "type" annotation token.
Tok.setKind(tok::annot_typename);
- setTypeAnnotation(Tok, Type.isInvalid() ? nullptr : Type.get());
+ setTypeAnnotation(Tok, Type);
if (SS.isNotEmpty()) // it was a C++ qualified type name.
Tok.setLocation(SS.getBeginLoc());
// End location stays the same
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index a33e40b..e9dbd50 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1902,7 +1902,7 @@
SourceLocation EndLoc = Tok.getLastLoc();
Tok.setKind(tok::annot_typename);
- setTypeAnnotation(Tok, Ty.isInvalid() ? nullptr : Ty.get());
+ setTypeAnnotation(Tok, Ty);
Tok.setAnnotationEndLoc(EndLoc);
Tok.setLocation(TypenameLoc);
PP.AnnotateCachedTokens(Tok);