Skip to content

Commit

Permalink
[Objective-C] Fix non-determinism in clang
Browse files Browse the repository at this point in the history
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

llvm-svn: 307296
  • Loading branch information
Mandeep Singh Grang committed Jul 6, 2017
1 parent e9bf7eb commit a2baff0
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
9 changes: 5 additions & 4 deletions clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
Expand Up @@ -146,7 +146,7 @@ namespace {

llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
llvm::DenseMap<ObjCInterfaceDecl *,
llvm::SmallPtrSet<ObjCIvarDecl *, 8> > ReferencedIvars;
llvm::SmallSetVector<ObjCIvarDecl *, 8> > ReferencedIvars;

// ivar bitfield grouping containers
llvm::DenseSet<const ObjCInterfaceDecl *> ObjCInterefaceHasBitfieldGroups;
Expand Down Expand Up @@ -1013,7 +1013,7 @@ void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
Setr = "\nextern \"C\" __declspec(dllimport) "
"void objc_setProperty (id, SEL, long, id, bool, bool);\n";
}

RewriteObjCMethodDecl(OID->getContainingInterface(),
PD->getSetterMethodDecl(), Setr);
Setr += "{ ";
Expand Down Expand Up @@ -3965,10 +3965,11 @@ void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
std::string &Result) {
// write out ivar offset symbols which have been referenced in an ivar
// access expression.
llvm::SmallPtrSet<ObjCIvarDecl *, 8> Ivars = ReferencedIvars[CDecl];
llvm::SmallSetVector<ObjCIvarDecl *, 8> Ivars = ReferencedIvars[CDecl];

if (Ivars.empty())
return;

llvm::DenseSet<std::pair<const ObjCInterfaceDecl*, unsigned> > GroupSymbolOutput;
for (ObjCIvarDecl *IvarDecl : Ivars) {
const ObjCInterfaceDecl *IDecl = IvarDecl->getContainingInterface();
Expand Down
45 changes: 45 additions & 0 deletions clang/test/Rewriter/objc-modern-metadata-visibility2.mm
@@ -0,0 +1,45 @@
// REQUIRES: abi-breaking-checks
// NOTE: This test has been split from objc-modern-metadata-visibility.mm in
// order to test with -reverse-iterate as this flag is only present with
// ABI_BREAKING_CHECKS.

// RUN: %clang_cc1 -E %s -o %t.mm -mllvm -reverse-iterate
// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -mllvm -reverse-iterate -o - | FileCheck %s
// rdar://11144048

@class NSString;

@interface NSObject {
Class isa;
}
@end

@interface Sub : NSObject {
int subIvar;
NSString *nsstring;
@private
id PrivateIvar;
}
@end

@implementation Sub
- (id) MyNSString { return subIvar ? PrivateIvar : nsstring; }
@end

@interface NSString @end
@implementation NSString @end

// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllimport) unsigned long OBJC_IVAR_$_Sub$subIvar;
// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" unsigned long OBJC_IVAR_$_Sub$PrivateIvar;
// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllimport) unsigned long OBJC_IVAR_$_Sub$nsstring;
// CHECK: #pragma warning(disable:4273)
// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllexport) unsigned long int OBJC_IVAR_$_Sub$subIvar
// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllexport) unsigned long int OBJC_IVAR_$_Sub$nsstring
// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" unsigned long int OBJC_IVAR_$_Sub$PrivateIvar
// CHECK: extern "C" __declspec(dllimport) struct _class_t OBJC_METACLASS_$_NSObject;
// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_METACLASS_$_Sub
// CHECK: extern "C" __declspec(dllimport) struct _class_t OBJC_CLASS_$_NSObject;
// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_Sub
// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_NSString;
// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_METACLASS_$_NSString
// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_NSString

0 comments on commit a2baff0

Please sign in to comment.