-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[lld-macho] Make ObjC category checker print the source file name of … #80221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…conflicting categories Summary: When printing category conflicts in the ObjC category checker, also print the source file name of the problematic categories. Currently we only print the object file name. This change is mostly useful only for thinLTO builds, where the object file name will be of form 999.arm64.lto.o and thus does not reveal any information about the original source file. Test Plan: Added test case + check-lld. Reviewers: Subscribers: Tasks: Tags:
@llvm/pr-subscribers-lld @llvm/pr-subscribers-lld-macho Author: None (alx32) ChangesSummary: When printing category conflicts in the ObjC category checker, also print the source file name of the problematic categories. Currently we only print the object file name. This change is mostly useful only for thinLTO builds, where the object file name will be of form 999.arm64.lto.o and thus does not reveal any information about the original source file. Test Plan: Added test case + check-lld. Full diff: https://github.com/llvm/llvm-project/pull/80221.diff 2 Files Affected:
diff --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp
index 7e8cec026d2f7..02009d4ed59cf 100644
--- a/lld/MachO/ObjC.cpp
+++ b/lld/MachO/ObjC.cpp
@@ -237,12 +237,24 @@ void ObjcCategoryChecker::parseMethods(const ConcatInputSection *methodsIsec,
StringRef newCatName =
getReferentString(*containerIsec->getRelocAt(catLayout.nameOffset));
+ auto formatObjAndSrcFileName = [](const InputSection *section) {
+ lld::macho::InputFile *inputFile = section->getFile();
+ std::string result = toString(inputFile);
+
+ auto objFile = dyn_cast_or_null<ObjFile>(inputFile);
+ if (objFile && objFile->compileUnit) {
+ result += " (" + objFile->sourceFile() + ")";
+ }
+
+ return result;
+ };
+
StringRef containerType = mc.kind == MCK_Category ? "category" : "class";
warn("method '" + methPrefix + methodName.val() +
"' has conflicting definitions:\n>>> defined in category " +
- newCatName + " from " + toString(containerIsec->getFile()) +
+ newCatName + " from " + formatObjAndSrcFileName(containerIsec) +
"\n>>> defined in " + containerType + " " + containerName + " from " +
- toString(mc.isec->getFile()));
+ formatObjAndSrcFileName(mc.isec));
}
}
diff --git a/lld/test/MachO/objc-category-conflicts.s b/lld/test/MachO/objc-category-conflicts.s
index 59a9ed50eb055..4ac8dc72c8668 100644
--- a/lld/test/MachO/objc-category-conflicts.s
+++ b/lld/test/MachO/objc-category-conflicts.s
@@ -3,6 +3,9 @@
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat1.s -o %t/cat1.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat2.s -o %t/cat2.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/klass.s -o %t/klass.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat1.s -g -o %t/cat1_w_sym.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat2.s -g -o %t/cat2_w_sym.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/klass.s -g -o %t/klass_w_sym.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat1.s --defsym MAKE_LOAD_METHOD=1 -o %t/cat1-with-load.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat2.s --defsym MAKE_LOAD_METHOD=1 -o %t/cat2-with-load.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/klass.s --defsym MAKE_LOAD_METHOD=1 -o %t/klass-with-load.o
@@ -14,6 +17,14 @@
# RUN: %no-fatal-warnings-lld --check-category-conflicts -dylib -lobjc %t/libklass.dylib %t/cat1.o \
# RUN: %t/cat2.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=CATCAT
+# RUN: %no-fatal-warnings-lld --check-category-conflicts -dylib -lobjc %t/klass_w_sym.o %t/cat1_w_sym.o %t/cat2_w_sym.o -o \
+# RUN: /dev/null 2>&1 | FileCheck %s --check-prefixes=CATCLS_W_SYM,CATCAT_W_SYM
+# RUN: %no-fatal-warnings-lld --check-category-conflicts -dylib -lobjc %t/libklass.dylib %t/cat1_w_sym.o \
+# RUN: %t/cat2_w_sym.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=CATCAT_W_SYM
+
+# RUN: %no-fatal-warnings-lld --check-category-conflicts -dylib -lobjc %t/klass.o %t/cat1.o %t/cat2.o -o \
+# RUN: /dev/null 2>&1 | FileCheck %s --check-prefixes=CATCLS,CATCAT
+
## Check that we don't emit spurious warnings around the +load method while
## still emitting the other warnings. Note that we have made separate
## `*-with-load.s` files for ease of comparison with ld64; ld64 will not warn
@@ -45,6 +56,24 @@
# CATCAT-NEXT: >>> defined in category Cat2 from {{.*}}cat2{{.*}}.o
# CATCAT-NEXT: >>> defined in category Cat1 from {{.*}}cat1{{.*}}.o
+
+# CATCLS_W_SYM: warning: method '+s1' has conflicting definitions:
+# CATCLS_W_SYM-NEXT: >>> defined in category Cat1 from {{.*}}cat1_w_sym{{.*}}.o ({{.*}}cat1.s{{.*}})
+# CATCLS_W_SYM-NEXT: >>> defined in class Foo from {{.*}}klass_w_sym{{.*}}.o ({{.*}}klass.s{{.*}})
+
+# CATCLS_W_SYM: warning: method '-m1' has conflicting definitions:
+# CATCLS_W_SYM-NEXT: >>> defined in category Cat1 from {{.*}}cat1_w_sym{{.*}}.o ({{.*}}cat1.s{{.*}})
+# CATCLS_W_SYM-NEXT: >>> defined in class Foo from {{.*}}klass_w_sym{{.*}}.o ({{.*}}klass.s{{.*}})
+
+# CATCAT_W_SYM: warning: method '+s2' has conflicting definitions:
+# CATCAT_W_SYM-NEXT: >>> defined in category Cat2 from {{.*}}cat2_w_sym{{.*}}.o ({{.*}}cat2.s{{.*}})
+# CATCAT_W_SYM-NEXT: >>> defined in category Cat1 from {{.*}}cat1_w_sym{{.*}}.o ({{.*}}cat1.s{{.*}})
+
+# CATCAT_W_SYM: warning: method '-m2' has conflicting definitions:
+# CATCAT_W_SYM-NEXT: >>> defined in category Cat2 from {{.*}}cat2_w_sym{{.*}}.o ({{.*}}cat2.s{{.*}})
+# CATCAT_W_SYM-NEXT: >>> defined in category Cat1 from {{.*}}cat1_w_sym{{.*}}.o ({{.*}}cat1.s{{.*}})
+
+
#--- cat1.s
.include "objc-macros.s"
@@ -55,7 +84,7 @@
## +(void) s1;
## +(void) s2;
## @end
-##
+##
## @implementation Foo(Cat1)
## -(void) m1 {}
## -(void) m2 {}
@@ -114,7 +143,7 @@ __OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat1:
## -(void) m2;
## +(void) s2;
## @end
-##
+##
## @implementation Foo(Cat2)
## -(void) m2 {}
## +(void) s2 {}
|
I'm curious how it looks like with (full)lto builds where bitcodes are merged. |
Good catch. In that case the file paths won't be valid. i.e it'll be something like:
However, I don't see an easy way to tell at this location if we're within the LTO scenario. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just a minor nit.
However, I don't see an easy way to tell at this location if we're within the LTO scenario.
That's unfortunate. Spitting out some RandomFile might lead someone on a wild goose chase and I would prefer (if possible) to not even emit the source file in that scenario. In any case, this is already a quality improvement.
lgtm |
…category (llvm#80221) When printing category conflicts in the ObjC category checker, also print the source file name of the problematic categories. Currently we only print the object file name. This change is mostly useful only for thinLTO builds, where the object file name will be of form 999.arm64.lto.o and thus does not reveal any information about the original source file. --------- Co-authored-by: Alex Borcan <[email protected]>
…category (llvm#80221) When printing category conflicts in the ObjC category checker, also print the source file name of the problematic categories. Currently we only print the object file name. This change is mostly useful only for thinLTO builds, where the object file name will be of form 999.arm64.lto.o and thus does not reveal any information about the original source file. --------- Co-authored-by: Alex Borcan <[email protected]>
When printing category conflicts in the ObjC category checker, also print the source file name of the problematic categories. Currently we only print the object file name. This change is mostly useful only for thinLTO builds, where the object file name will be of form 999.arm64.lto.o and thus does not reveal any information about the original source file.