Skip to content

Commit 70922a4

Browse files
author
Mandeep Singh Grang
committed
[Objective-C] Fix non-determinism in clang
Summary: Iteration of the unordered Ivars causes objc-modern-metadata-visibility.mm (uncovered by reverse iterating SmallPtrSet). Reviewers: dblaikie, davide, rsmith Reviewed By: dblaikie Subscribers: cfe-commits, llvm-commits Differential Revision: https://reviews.llvm.org/D34860 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@307296 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 5bf57df commit 70922a4

File tree

2 files changed

+50
-4
lines changed

2 files changed

+50
-4
lines changed

lib/Frontend/Rewrite/RewriteModernObjC.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ namespace {
146146

147147
llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
148148
llvm::DenseMap<ObjCInterfaceDecl *,
149-
llvm::SmallPtrSet<ObjCIvarDecl *, 8> > ReferencedIvars;
149+
llvm::SmallSetVector<ObjCIvarDecl *, 8> > ReferencedIvars;
150150

151151
// ivar bitfield grouping containers
152152
llvm::DenseSet<const ObjCInterfaceDecl *> ObjCInterefaceHasBitfieldGroups;
@@ -1013,7 +1013,7 @@ void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
10131013
Setr = "\nextern \"C\" __declspec(dllimport) "
10141014
"void objc_setProperty (id, SEL, long, id, bool, bool);\n";
10151015
}
1016-
1016+
10171017
RewriteObjCMethodDecl(OID->getContainingInterface(),
10181018
PD->getSetterMethodDecl(), Setr);
10191019
Setr += "{ ";
@@ -3965,10 +3965,11 @@ void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
39653965
std::string &Result) {
39663966
// write out ivar offset symbols which have been referenced in an ivar
39673967
// access expression.
3968-
llvm::SmallPtrSet<ObjCIvarDecl *, 8> Ivars = ReferencedIvars[CDecl];
3968+
llvm::SmallSetVector<ObjCIvarDecl *, 8> Ivars = ReferencedIvars[CDecl];
3969+
39693970
if (Ivars.empty())
39703971
return;
3971-
3972+
39723973
llvm::DenseSet<std::pair<const ObjCInterfaceDecl*, unsigned> > GroupSymbolOutput;
39733974
for (ObjCIvarDecl *IvarDecl : Ivars) {
39743975
const ObjCInterfaceDecl *IDecl = IvarDecl->getContainingInterface();
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// REQUIRES: abi-breaking-checks
2+
// NOTE: This test has been split from objc-modern-metadata-visibility.mm in
3+
// order to test with -reverse-iterate as this flag is only present with
4+
// ABI_BREAKING_CHECKS.
5+
6+
// RUN: %clang_cc1 -E %s -o %t.mm -mllvm -reverse-iterate
7+
// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -mllvm -reverse-iterate -o - | FileCheck %s
8+
// rdar://11144048
9+
10+
@class NSString;
11+
12+
@interface NSObject {
13+
Class isa;
14+
}
15+
@end
16+
17+
@interface Sub : NSObject {
18+
int subIvar;
19+
NSString *nsstring;
20+
@private
21+
id PrivateIvar;
22+
}
23+
@end
24+
25+
@implementation Sub
26+
- (id) MyNSString { return subIvar ? PrivateIvar : nsstring; }
27+
@end
28+
29+
@interface NSString @end
30+
@implementation NSString @end
31+
32+
// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllimport) unsigned long OBJC_IVAR_$_Sub$subIvar;
33+
// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" unsigned long OBJC_IVAR_$_Sub$PrivateIvar;
34+
// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllimport) unsigned long OBJC_IVAR_$_Sub$nsstring;
35+
// CHECK: #pragma warning(disable:4273)
36+
// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllexport) unsigned long int OBJC_IVAR_$_Sub$subIvar
37+
// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllexport) unsigned long int OBJC_IVAR_$_Sub$nsstring
38+
// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" unsigned long int OBJC_IVAR_$_Sub$PrivateIvar
39+
// CHECK: extern "C" __declspec(dllimport) struct _class_t OBJC_METACLASS_$_NSObject;
40+
// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_METACLASS_$_Sub
41+
// CHECK: extern "C" __declspec(dllimport) struct _class_t OBJC_CLASS_$_NSObject;
42+
// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_Sub
43+
// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_NSString;
44+
// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_METACLASS_$_NSString
45+
// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_NSString

0 commit comments

Comments
 (0)