From: John McCall Date: Wed, 10 Apr 2013 06:08:21 +0000 (+0000) Subject: Don't crash when mangling types defined in ObjC class extensions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0baaabb7174c8e512ea52bc36687dc31ff68b09f;p=clang Don't crash when mangling types defined in ObjC class extensions. The original test case here was mangling a type name for TBAA, but we can provoke this in C++11 easily enough. rdar://13434937 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179153 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 21c499317f..0f4881e24e 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -1095,6 +1095,15 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, mangleSourceName(FD->getIdentifier()); break; } + + // Class extensions have no name as a category, and it's possible + // for them to be the semantic parent of certain declarations + // (primarily, tag decls defined within declarations). Such + // declarations will always have internal linkage, so the name + // doesn't really matter, but we shouldn't crash on them. For + // safety, just handle all ObjC containers here. + if (isa(ND)) + break; // We must have an anonymous struct. const TagDecl *TD = cast(ND); diff --git a/test/CodeGenObjCXX/mangle.mm b/test/CodeGenObjCXX/mangle.mm index 2521c6076a..45a93a196d 100644 --- a/test/CodeGenObjCXX/mangle.mm +++ b/test/CodeGenObjCXX/mangle.mm @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - | FileCheck %s // CHECK: @"_ZZ11+[A shared]E1a" = internal global // CHECK: @"_ZZ11-[A(Foo) f]E1a" = internal global @@ -54,3 +54,27 @@ uiIsVisible(); } @end + +// rdar://13434937 +// +// Don't crash when mangling an enum whose semantic context +// is a class extension (which looks anonymous in the AST). +// The other tests here are just for coverage. +@interface Test2 @end +@interface Test2 () +@property (assign) enum { T2x, T2y, T2z } axis; +@end +@interface Test2 (a) +@property (assign) enum { T2i, T2j, T2k } dimension; +@end +@implementation Test2 { +@public + enum { T2a, T2b, T2c } alt_axis; +} +@end +template struct Test2Template { Test2Template() {} }; // must have a member that we'll instantiate and mangle +void test2(Test2 *t) { + Test2Template t0; + Test2Template t1; + Test2Templatealt_axis)> t2; +}