This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG9fad9de5c003: [modules] Fix IRGen assertion on accessing
ObjC ivar inside a method. (authored by vsapsai).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D110280/new/
https://reviews.llvm.org/D110280
Files:
clang/include/clang/AST/DeclObjC.h
clang/lib/AST/RecordLayoutBuilder.cpp
clang/lib/Serialization/ASTReaderDecl.cpp
clang/test/Modules/merge-objc-interface.m
Index: clang/test/Modules/merge-objc-interface.m
===================================================================
--- /dev/null
+++ clang/test/Modules/merge-objc-interface.m
@@ -0,0 +1,105 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: %clang_cc1 -emit-llvm -o %t/test.bc -F%t/Frameworks %t/test.m \
+// RUN: -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache
+// RUN: %clang_cc1 -emit-llvm -o %t/test.bc -F%t/Frameworks %t/test-functions.m \
+// RUN: -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache
+
+// Test a case when Objective-C interface ivars are present in two different modules.
+
+//--- Frameworks/Foundation.framework/Headers/Foundation.h
+@interface NSObject
+@end
+
+//--- Frameworks/Foundation.framework/Modules/module.modulemap
+framework module Foundation {
+ header "Foundation.h"
+ export *
+}
+
+//--- Frameworks/ObjCInterface.framework/Headers/ObjCInterface.h
+#import <Foundation/Foundation.h>
+@interface ObjCInterface : NSObject {
+@public
+ id _item;
+}
+@end
+
+@interface WithBitFields : NSObject {
+@public
+ int x: 3;
+ int y: 4;
+}
+@end
+
+//--- Frameworks/ObjCInterface.framework/Modules/module.modulemap
+framework module ObjCInterface {
+ header "ObjCInterface.h"
+ export *
+}
+
+//--- Frameworks/ObjCInterfaceCopy.framework/Headers/ObjCInterfaceCopy.h
+#import <Foundation/Foundation.h>
+@interface ObjCInterface : NSObject {
+@public
+ id _item;
+}
+@end
+
+@interface WithBitFields : NSObject {
+@public
+ int x: 3;
+ int y: 4;
+}
+@end
+
+// Inlined function present only in Copy.framework to make sure it uses decls from Copy module.
+__attribute__((always_inline)) void inlinedIVarAccessor(ObjCInterface *obj, WithBitFields *bitFields) {
+ obj->_item = 0;
+ bitFields->x = 0;
+}
+
+//--- Frameworks/ObjCInterfaceCopy.framework/Modules/module.modulemap
+framework module ObjCInterfaceCopy {
+ header "ObjCInterfaceCopy.h"
+ export *
+}
+
+//--- test.m
+#import <ObjCInterface/ObjCInterface.h>
+#import <ObjCInterfaceCopy/ObjCInterfaceCopy.h>
+
+@implementation ObjCInterface
+- (void)test:(id)item {
+ _item = item;
+}
+@end
+
+@implementation WithBitFields
+- (void)reset {
+ x = 0;
+ y = 0;
+}
+@end
+
+//--- test-functions.m
+#import <ObjCInterface/ObjCInterface.h>
+
+void testAccessIVar(ObjCInterface *obj, id item) {
+ obj->_item = item;
+}
+void testAccessBitField(WithBitFields *obj) {
+ obj->x = 0;
+}
+
+#import <ObjCInterfaceCopy/ObjCInterfaceCopy.h>
+
+void testAccessIVarLater(ObjCInterface *obj, id item) {
+ obj->_item = item;
+}
+void testAccessBitFieldLater(WithBitFields *obj) {
+ obj->y = 0;
+}
+void testInlinedFunction(ObjCInterface *obj, WithBitFields *bitFields) {
+ inlinedIVarAccessor(obj, bitFields);
+}
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3350,6 +3350,9 @@
return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition()
: nullptr;
+ if (auto *OID = dyn_cast<ObjCInterfaceDecl>(DC))
+ return OID->getDefinition();
+
// We can see the TU here only if we have no Sema object. In that case,
// there's no TU scope to look in, so using the DC alone is sufficient.
if (auto *TU = dyn_cast<TranslationUnitDecl>(DC))
Index: clang/lib/AST/RecordLayoutBuilder.cpp
===================================================================
--- clang/lib/AST/RecordLayoutBuilder.cpp
+++ clang/lib/AST/RecordLayoutBuilder.cpp
@@ -3404,6 +3404,7 @@
uint64_t ASTContext::lookupFieldBitOffset(const ObjCInterfaceDecl *OID,
const ObjCImplementationDecl *ID,
const ObjCIvarDecl *Ivar) const {
+ Ivar = Ivar->getCanonicalDecl();
const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
// FIXME: We should eliminate the need to have ObjCImplementationDecl passed
Index: clang/include/clang/AST/DeclObjC.h
===================================================================
--- clang/include/clang/AST/DeclObjC.h
+++ clang/include/clang/AST/DeclObjC.h
@@ -1955,6 +1955,13 @@
const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
+ ObjCIvarDecl *getCanonicalDecl() override {
+ return cast<ObjCIvarDecl>(FieldDecl::getCanonicalDecl());
+ }
+ const ObjCIvarDecl *getCanonicalDecl() const {
+ return const_cast<ObjCIvarDecl *>(this)->getCanonicalDecl();
+ }
+
void setAccessControl(AccessControl ac) { DeclAccess = ac; }
AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits