mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-23 17:48:03 +00:00
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.
This commit is contained in:
parent
5074776de4
commit
3308732300
@ -763,13 +763,17 @@ public:
|
||||
}
|
||||
|
||||
/// getTypeAnnotation - Read a parsed type out of an annotation token.
|
||||
static ParsedType getTypeAnnotation(const Token &Tok) {
|
||||
static TypeResult getTypeAnnotation(const Token &Tok) {
|
||||
if (!Tok.getAnnotationValue())
|
||||
return TypeError();
|
||||
return ParsedType::getFromOpaquePtr(Tok.getAnnotationValue());
|
||||
}
|
||||
|
||||
private:
|
||||
static void setTypeAnnotation(Token &Tok, ParsedType T) {
|
||||
Tok.setAnnotationValue(T.getAsOpaquePtr());
|
||||
static void setTypeAnnotation(Token &Tok, TypeResult T) {
|
||||
assert((T.isInvalid() || T.get()) &&
|
||||
"produced a valid-but-null type annotation?");
|
||||
Tok.setAnnotationValue(T.isInvalid() ? nullptr : T.get().getAsOpaquePtr());
|
||||
}
|
||||
|
||||
static NamedDecl *getNonTypeAnnotation(const Token &Tok) {
|
||||
|
@ -667,6 +667,13 @@ public:
|
||||
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
|
||||
unsigned &DiagID, ParsedType Rep,
|
||||
const PrintingPolicy &Policy);
|
||||
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
|
||||
unsigned &DiagID, TypeResult Rep,
|
||||
const PrintingPolicy &Policy) {
|
||||
if (Rep.isInvalid())
|
||||
return SetTypeSpecError();
|
||||
return SetTypeSpecType(T, Loc, PrevSpec, DiagID, Rep.get(), Policy);
|
||||
}
|
||||
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
|
||||
unsigned &DiagID, Decl *Rep, bool Owned,
|
||||
const PrintingPolicy &Policy);
|
||||
|
@ -3217,16 +3217,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
||||
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 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
||||
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;
|
||||
|
||||
|
@ -1151,13 +1151,10 @@ TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
|
||||
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 @@ TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
|
||||
// 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 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
|
||||
// : 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 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
|
||||
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 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
|
||||
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 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
|
||||
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 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
|
||||
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
|
||||
|
@ -1455,7 +1455,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
|
||||
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);
|
||||
|
@ -2147,12 +2147,8 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
|
||||
|
||||
// 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();
|
||||
|
||||
|
@ -2978,7 +2978,7 @@ bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
|
||||
InMessageExpression)
|
||||
return false;
|
||||
|
||||
ParsedType Type;
|
||||
TypeResult Type;
|
||||
|
||||
if (Tok.is(tok::annot_typename))
|
||||
Type = getTypeAnnotation(Tok);
|
||||
@ -2988,7 +2988,8 @@ bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
|
||||
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))
|
||||
|
@ -1321,7 +1321,7 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
|
||||
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 @@ void Parser::AnnotateTemplateIdTokenAsType(CXXScopeSpec &SS,
|
||||
/*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
|
||||
|
@ -1902,7 +1902,7 @@ bool Parser::TryAnnotateTypeOrScopeToken() {
|
||||
|
||||
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);
|
||||
|
@ -298,6 +298,11 @@ namespace ArrayMemberAccess {
|
||||
}
|
||||
}
|
||||
|
||||
namespace UndeclaredBaseTemplate {
|
||||
template<class> struct imp;
|
||||
template<class T> struct is_member_function_pointer : undeclared<imp<T>::member> {}; // expected-error {{unknown template name 'undeclared'}}
|
||||
}
|
||||
|
||||
// PR11109 must appear at the end of the source file
|
||||
class pr11109r3 { // expected-note{{to match this '{'}}
|
||||
public // expected-error{{expected ':'}} expected-error{{expected '}'}} expected-error{{expected ';' after class}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user