From c9b67096de0130558e13219673f8dba34b254137 Mon Sep 17 00:00:00 2001 From: Ben Langmuir Date: Mon, 12 Jan 2015 19:27:00 +0000 Subject: [PATCH] Fix bogus 'method is unavailable' errors with modules This just tweaks the fix from r224892 (which handled PCHs) to work with modules, where we will serialize each method individually and hence the hasMoreThanOneDecl bit needs to be updated as we add the methods. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@225659 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Serialization/ASTReader.cpp | 10 +++++--- .../Inputs/attr-unavailable/module.modulemap | 4 +++ test/Modules/Inputs/attr-unavailable/oneA.h | 4 +++ test/Modules/Inputs/attr-unavailable/oneB.h | 5 ++++ test/Modules/Inputs/attr-unavailable/oneC.h | 3 +++ test/Modules/Inputs/attr-unavailable/two.h | 6 +++++ test/Modules/attr-unavailable.m | 25 +++++++++++++++++++ 7 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 test/Modules/Inputs/attr-unavailable/module.modulemap create mode 100644 test/Modules/Inputs/attr-unavailable/oneA.h create mode 100644 test/Modules/Inputs/attr-unavailable/oneB.h create mode 100644 test/Modules/Inputs/attr-unavailable/oneC.h create mode 100644 test/Modules/Inputs/attr-unavailable/two.h create mode 100644 test/Modules/attr-unavailable.m diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 7d6565aac3..416164ebb7 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -7161,13 +7161,17 @@ void ASTReader::ReadMethodPool(Selector Sel) { Sema &S = *getSema(); Sema::GlobalMethodPool::iterator Pos = S.MethodPool.insert(std::make_pair(Sel, Sema::GlobalMethods())).first; - - addMethodsToPool(S, Visitor.getInstanceMethods(), Pos->second.first); - addMethodsToPool(S, Visitor.getFactoryMethods(), Pos->second.second); + Pos->second.first.setBits(Visitor.getInstanceBits()); Pos->second.first.setHasMoreThanOneDecl(Visitor.instanceHasMoreThanOneDecl()); Pos->second.second.setBits(Visitor.getFactoryBits()); Pos->second.second.setHasMoreThanOneDecl(Visitor.factoryHasMoreThanOneDecl()); + + // Add methods to the global pool *after* setting hasMoreThanOneDecl, since + // when building a module we keep every method individually and may need to + // update hasMoreThanOneDecl as we add the methods. + addMethodsToPool(S, Visitor.getInstanceMethods(), Pos->second.first); + addMethodsToPool(S, Visitor.getFactoryMethods(), Pos->second.second); } void ASTReader::ReadKnownNamespaces( diff --git a/test/Modules/Inputs/attr-unavailable/module.modulemap b/test/Modules/Inputs/attr-unavailable/module.modulemap new file mode 100644 index 0000000000..a5159420c2 --- /dev/null +++ b/test/Modules/Inputs/attr-unavailable/module.modulemap @@ -0,0 +1,4 @@ +module two { header "two.h" } +module oneA { header "oneA.h" } +module oneB { header "oneB.h" export oneA } +module oneC { header "oneC.h" } diff --git a/test/Modules/Inputs/attr-unavailable/oneA.h b/test/Modules/Inputs/attr-unavailable/oneA.h new file mode 100644 index 0000000000..a4e572ffac --- /dev/null +++ b/test/Modules/Inputs/attr-unavailable/oneA.h @@ -0,0 +1,4 @@ +@interface C +-(void)method2 __attribute__((unavailable)); +-(void)method3 __attribute__((unavailable)); +@end diff --git a/test/Modules/Inputs/attr-unavailable/oneB.h b/test/Modules/Inputs/attr-unavailable/oneB.h new file mode 100644 index 0000000000..b9536ad15b --- /dev/null +++ b/test/Modules/Inputs/attr-unavailable/oneB.h @@ -0,0 +1,5 @@ +@import oneA; + +@interface D +-(void)method2; +@end diff --git a/test/Modules/Inputs/attr-unavailable/oneC.h b/test/Modules/Inputs/attr-unavailable/oneC.h new file mode 100644 index 0000000000..9dc305e70f --- /dev/null +++ b/test/Modules/Inputs/attr-unavailable/oneC.h @@ -0,0 +1,3 @@ +@interface E +-(void)method3; +@end diff --git a/test/Modules/Inputs/attr-unavailable/two.h b/test/Modules/Inputs/attr-unavailable/two.h new file mode 100644 index 0000000000..0423f61010 --- /dev/null +++ b/test/Modules/Inputs/attr-unavailable/two.h @@ -0,0 +1,6 @@ +@interface A +-(void)method1; +@end +@interface B +-(void)method1 __attribute__((unavailable)); +@end diff --git a/test/Modules/attr-unavailable.m b/test/Modules/attr-unavailable.m new file mode 100644 index 0000000000..0188a84d98 --- /dev/null +++ b/test/Modules/attr-unavailable.m @@ -0,0 +1,25 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/attr-unavailable %s -fsyntax-only -verify + +@import two; +void f(id x) { + [x method1]; +} + +@import oneA; +void g(id x) { + [x method2]; // expected-error{{'method2' is unavailable}} + // expected-note@oneA.h:2 {{'method2' has been explicitly marked unavailable here}} + [x method3]; // expected-error{{'method3' is unavailable}} + // expected-note@oneA.h:3 {{'method3' has been explicitly marked unavailable here}} +} + +@import oneB; +void h(id x) { + [x method2]; // could be from interface D in module oneB +} + +@import oneC; +void i(id x) { + [x method3]; // could be from interface E in module oncC +} -- 2.40.0