mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-04 14:16:09 +00:00
Really protect from infinite loop when there are objc method redeclarations.
Serialization part will come later. llvm-svn: 141950
This commit is contained in:
parent
e35b3aae52
commit
dcaaa21fbe
@ -128,6 +128,9 @@ private:
|
|||||||
// Method has a definition.
|
// Method has a definition.
|
||||||
unsigned IsDefined : 1;
|
unsigned IsDefined : 1;
|
||||||
|
|
||||||
|
// Method redeclaration in the same interface.
|
||||||
|
unsigned IsRedeclaration : 1;
|
||||||
|
|
||||||
// NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
|
// NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
|
||||||
/// @required/@optional
|
/// @required/@optional
|
||||||
unsigned DeclImplementation : 2;
|
unsigned DeclImplementation : 2;
|
||||||
@ -220,7 +223,7 @@ private:
|
|||||||
DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
|
DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
|
||||||
IsInstance(isInstance), IsVariadic(isVariadic),
|
IsInstance(isInstance), IsVariadic(isVariadic),
|
||||||
IsSynthesized(isSynthesized),
|
IsSynthesized(isSynthesized),
|
||||||
IsDefined(isDefined),
|
IsDefined(isDefined), IsRedeclaration(0),
|
||||||
DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
|
DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
|
||||||
RelatedResultType(HasRelatedResultType),
|
RelatedResultType(HasRelatedResultType),
|
||||||
SelLocsKind(SelLoc_StandardNoSpace),
|
SelLocsKind(SelLoc_StandardNoSpace),
|
||||||
@ -267,6 +270,10 @@ public:
|
|||||||
|
|
||||||
/// \brief Note whether this method has a related result type.
|
/// \brief Note whether this method has a related result type.
|
||||||
void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; }
|
void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; }
|
||||||
|
|
||||||
|
/// \brief True if this is a method redeclaration in the same interface.
|
||||||
|
bool isRedeclaration() const { return IsRedeclaration; }
|
||||||
|
void setAsRedeclaration(const ObjCMethodDecl *PrevMethod);
|
||||||
|
|
||||||
// Location information, modeled after the Stmt API.
|
// Location information, modeled after the Stmt API.
|
||||||
SourceLocation getLocStart() const { return getLocation(); }
|
SourceLocation getLocStart() const { return getLocation(); }
|
||||||
|
@ -351,6 +351,12 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
|
|||||||
HasRelatedResultType);
|
HasRelatedResultType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {
|
||||||
|
assert(PrevMethod);
|
||||||
|
getASTContext().setObjCMethodRedeclaration(PrevMethod, this);
|
||||||
|
IsRedeclaration = true;
|
||||||
|
}
|
||||||
|
|
||||||
void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
|
void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
|
||||||
ArrayRef<ParmVarDecl*> Params,
|
ArrayRef<ParmVarDecl*> Params,
|
||||||
ArrayRef<SourceLocation> SelLocs) {
|
ArrayRef<SourceLocation> SelLocs) {
|
||||||
@ -418,6 +424,12 @@ ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
|
|||||||
Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
|
Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Redecl && isRedeclaration()) {
|
||||||
|
// This is the last redeclaration, go back to the first method.
|
||||||
|
return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
|
||||||
|
isInstanceMethod());
|
||||||
|
}
|
||||||
|
|
||||||
return Redecl ? Redecl : this;
|
return Redecl ? Redecl : this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2168,7 +2168,7 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
|
|||||||
Method->setInvalidDecl();
|
Method->setInvalidDecl();
|
||||||
} else {
|
} else {
|
||||||
if (PrevMethod)
|
if (PrevMethod)
|
||||||
Context.setObjCMethodRedeclaration(PrevMethod, Method);
|
Method->setAsRedeclaration(PrevMethod);
|
||||||
InsMap[Method->getSelector()] = Method;
|
InsMap[Method->getSelector()] = Method;
|
||||||
/// The following allows us to typecheck messages to "id".
|
/// The following allows us to typecheck messages to "id".
|
||||||
AddInstanceMethodToGlobalPool(Method);
|
AddInstanceMethodToGlobalPool(Method);
|
||||||
@ -2189,7 +2189,7 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
|
|||||||
Method->setInvalidDecl();
|
Method->setInvalidDecl();
|
||||||
} else {
|
} else {
|
||||||
if (PrevMethod)
|
if (PrevMethod)
|
||||||
Context.setObjCMethodRedeclaration(PrevMethod, Method);
|
Method->setAsRedeclaration(PrevMethod);
|
||||||
ClsMap[Method->getSelector()] = Method;
|
ClsMap[Method->getSelector()] = Method;
|
||||||
/// The following allows us to typecheck messages to "Class".
|
/// The following allows us to typecheck messages to "Class".
|
||||||
AddFactoryMethodToGlobalPool(Method);
|
AddFactoryMethodToGlobalPool(Method);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// RUN: %clang_cc1 -x objective-c -emit-pch -o %t
|
// RUN: %clang_cc1 -x objective-c -emit-pch -o %t
|
||||||
|
// RUN: %clang_cc1 -x objective-c -emit-pch -o %t -D IMPL
|
||||||
|
|
||||||
// Avoid infinite loop because of method redeclarations.
|
// Avoid infinite loop because of method redeclarations.
|
||||||
|
|
||||||
@ -8,6 +9,10 @@
|
|||||||
-(void)meth;
|
-(void)meth;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
#ifdef IMPL
|
||||||
|
|
||||||
@implementation Foo
|
@implementation Foo
|
||||||
-(void)meth { }
|
-(void)meth { }
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user