From: Akira Hatanaka Date: Wed, 17 Aug 2016 19:42:22 +0000 (+0000) Subject: [CodeGen][ObjC] Fix infinite recursion in getObjCEncodingForTypeImpl. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f33b253680ee5dab7b7470b748e4b1afadea47ac;p=clang [CodeGen][ObjC] Fix infinite recursion in getObjCEncodingForTypeImpl. Check that ExpandStructures is true before visiting the list of ivars. rdar://problem/27135221 Differential revision: https://reviews.llvm.org/D22929 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@278956 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 49948a5d41..425aeac3c0 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -5906,18 +5906,20 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, ObjCInterfaceDecl *OI = T->castAs()->getInterface(); S += '{'; S += OI->getObjCRuntimeNameAsString(); - S += '='; - SmallVector Ivars; - DeepCollectObjCIvars(OI, true, Ivars); - for (unsigned i = 0, e = Ivars.size(); i != e; ++i) { - const FieldDecl *Field = cast(Ivars[i]); - if (Field->isBitField()) - getObjCEncodingForTypeImpl(Field->getType(), S, false, true, Field); - else - getObjCEncodingForTypeImpl(Field->getType(), S, false, true, FD, - false, false, false, false, false, - EncodePointerToObjCTypedef, - NotEncodedT); + if (ExpandStructures) { + S += '='; + SmallVector Ivars; + DeepCollectObjCIvars(OI, true, Ivars); + for (unsigned i = 0, e = Ivars.size(); i != e; ++i) { + const FieldDecl *Field = cast(Ivars[i]); + if (Field->isBitField()) + getObjCEncodingForTypeImpl(Field->getType(), S, false, true, Field); + else + getObjCEncodingForTypeImpl(Field->getType(), S, false, true, FD, + false, false, false, false, false, + EncodePointerToObjCTypedef, + NotEncodedT); + } } S += '}'; return; diff --git a/test/CodeGenObjCXX/encode.mm b/test/CodeGenObjCXX/encode.mm index e0171efbed..6b7fc70e25 100644 --- a/test/CodeGenObjCXX/encode.mm +++ b/test/CodeGenObjCXX/encode.mm @@ -224,3 +224,24 @@ namespace PR17142 { // CHECK: @_ZN7PR171421xE = constant [14 x i8] c"{E=^^?i^^?ii}\00" extern const char x[] = @encode(E); } + +// This test used to cause infinite recursion. +template +struct S { + typedef T Ty; + Ty *t; +}; + +@interface N +{ + S a; +} +@end + +@implementation N +@end + +const char *expand_struct() { + // CHECK: @{{.*}} = private unnamed_addr constant [16 x i8] c"{N={S=^{N}}}\00" + return @encode(N); +}