]> granicus.if.org Git - clang/commitdiff
Fix bogus 'method is unavailable' errors with modules
authorBen Langmuir <blangmuir@apple.com>
Mon, 12 Jan 2015 19:27:00 +0000 (19:27 +0000)
committerBen Langmuir <blangmuir@apple.com>
Mon, 12 Jan 2015 19:27:00 +0000 (19:27 +0000)
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
test/Modules/Inputs/attr-unavailable/module.modulemap [new file with mode: 0644]
test/Modules/Inputs/attr-unavailable/oneA.h [new file with mode: 0644]
test/Modules/Inputs/attr-unavailable/oneB.h [new file with mode: 0644]
test/Modules/Inputs/attr-unavailable/oneC.h [new file with mode: 0644]
test/Modules/Inputs/attr-unavailable/two.h [new file with mode: 0644]
test/Modules/attr-unavailable.m [new file with mode: 0644]

index 7d6565aac38f481704fc8114c2f127a44c27fe93..416164ebb7d244bed03906caede3bb7033420a41 100644 (file)
@@ -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 (file)
index 0000000..a515942
--- /dev/null
@@ -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 (file)
index 0000000..a4e572f
--- /dev/null
@@ -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 (file)
index 0000000..b9536ad
--- /dev/null
@@ -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 (file)
index 0000000..9dc305e
--- /dev/null
@@ -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 (file)
index 0000000..0423f61
--- /dev/null
@@ -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 (file)
index 0000000..0188a84
--- /dev/null
@@ -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
+}