From 0cd00be2813db976d62fb88fa26ccca8d6791823 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Mon, 14 May 2012 22:48:56 +0000 Subject: [PATCH] objc: allow typedef'ing an id to a pointer to a c-struct only. // rdar://11356439 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156788 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 22 ++++++++++++++++------ test/SemaObjC/id.m | 12 +++++++++++- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 3e660b5986..9e7f28b24d 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1518,12 +1518,22 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { switch (TypeID->getLength()) { default: break; case 2: - if (!TypeID->isStr("id")) - break; - Context.setObjCIdRedefinitionType(New->getUnderlyingType()); - // Install the built-in type for 'id', ignoring the current definition. - New->setTypeForDecl(Context.getObjCIdType().getTypePtr()); - return; + { + if (!TypeID->isStr("id")) + break; + QualType T = New->getUnderlyingType(); + if (!T->isPointerType()) + break; + if (!T->isVoidPointerType()) { + QualType PT = T->getAs()->getPointeeType(); + if (!PT->isStructureType()) + break; + } + Context.setObjCIdRedefinitionType(T); + // Install the built-in type for 'id', ignoring the current definition. + New->setTypeForDecl(Context.getObjCIdType().getTypePtr()); + return; + } case 5: if (!TypeID->isStr("Class")) break; diff --git a/test/SemaObjC/id.m b/test/SemaObjC/id.m index 27b84dedf8..ced406ebd2 100644 --- a/test/SemaObjC/id.m +++ b/test/SemaObjC/id.m @@ -16,6 +16,16 @@ void foo() { } // Test attempt to redefine 'id' in an incompatible fashion. -typedef int id; // FIXME: Decide how we want to deal with this (now that 'id' is more of a built-in type). +// rdar://11356439 +typedef int id; // expected-error {{typedef redefinition with different types ('int' vs 'id')}} id b; +typedef double id; // expected-error {{typedef redefinition with different types ('double' vs 'id')}} + +typedef char *id; // expected-error {{typedef redefinition with different types ('char *' vs 'id')}} + +typedef union U{ int iu; } *id; // expected-error {{typedef redefinition with different types ('union U *' vs 'id')}} + +void test11356439(id o) { + o->x; // expected-error {{member reference base type 'id' is not a structure or union}} +} -- 2.40.0