vsk created this revision.
vsk added reviewers: ributzka, steven_wu, calixte, marco-c.

Make sure that symbols needed to implement runtime support for gcov are
exported when using an export list on Darwin.

Without the clang driver exporting these symbols, the linker hides them,
resulting in tapi verification failures.

rdar://45944768


https://reviews.llvm.org/D55151

Files:
  clang/include/clang/Driver/ToolChain.h
  clang/lib/Driver/ToolChain.cpp
  clang/lib/Driver/ToolChains/Darwin.cpp
  clang/test/Driver/darwin-ld.c
  compiler-rt/test/profile/instrprof-darwin-exports.c

Index: compiler-rt/test/profile/instrprof-darwin-exports.c
===================================================================
--- compiler-rt/test/profile/instrprof-darwin-exports.c
+++ compiler-rt/test/profile/instrprof-darwin-exports.c
@@ -8,6 +8,9 @@
 // RUN: %clang_profgen -Werror -fcoverage-mapping -Wl,-exported_symbols_list,%t.exports -o %t %s 2>&1 | tee -a %t.log
 // RUN: cat %t.log | count 0
 
+// RUN: %clang -Werror -Wl,-exported_symbols_list,%t.exports --coverage -o %t.gcov %s | tee -a %t.gcov.log
+// RUN: cat %t.gcov.log | count 0
+
 // The default set of weak external symbols should match the set of symbols
 // exported by clang. See Darwin::addProfileRTLibs.
 
@@ -16,4 +19,9 @@
 // RUN: nm -jUg %t > %t.clang.exports
 // RUN: diff %t.default.exports %t.clang.exports
 
+// RUN: %clang -Werror --coverage -o %t.gcov.default %s
+// RUN: nm -jUg %t.gcov | grep -v __mh_execute_header > %t.gcov.exports
+// RUN: nm -jUg %t.gcov.default | grep -v __mh_execute_header > %t.gcov.default.exports
+// RUN: diff %t.gcov.default.exports %t.gcov.exports
+
 int main() {}
Index: clang/test/Driver/darwin-ld.c
===================================================================
--- clang/test/Driver/darwin-ld.c
+++ clang/test/Driver/darwin-ld.c
@@ -341,10 +341,22 @@
 // RUN: FileCheck -check-prefix=PROFILE_EXPORT %s < %t.log
 // PROFILE_EXPORT: "-exported_symbol" "___llvm_profile_filename" "-exported_symbol" "___llvm_profile_raw_version" "-exported_symbol" "_lprofCurFilename"
 //
-// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -### %t.o 2> %t.log
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate --coverage -### %t.o 2> %t.log
 // RUN: FileCheck -check-prefix=NO_PROFILE_EXPORT %s < %t.log
 // NO_PROFILE_EXPORT-NOT: "-exported_symbol"
 //
+// RUN: %clang -target x86_64-apple-darwin12 --coverage -exported_symbols_list /dev/null -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=GCOV_EXPORT %s < %t.log
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-arcs -Wl,-exported_symbols_list,/dev/null -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=GCOV_EXPORT %s < %t.log
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-arcs -Wl,-exported_symbol,foo -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=GCOV_EXPORT %s < %t.log
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-arcs -Xlinker -exported_symbol -Xlinker foo -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=GCOV_EXPORT %s < %t.log
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-arcs -Xlinker -exported_symbols_list -Xlinker /dev/null -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=GCOV_EXPORT %s < %t.log
+// GCOV_EXPORT: "-exported_symbol" "___gcov_flush"
+//
 // Check that we can pass the outliner down to the linker.
 // RUN: env IPHONEOS_DEPLOYMENT_TARGET=7.0 \
 // RUN:   %clang -target arm64-apple-darwin -moutline -### %t.o 2> %t.log
Index: clang/lib/Driver/ToolChains/Darwin.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Darwin.cpp
+++ clang/lib/Driver/ToolChains/Darwin.cpp
@@ -1034,11 +1034,17 @@
   // runtime, automatically export symbols necessary to implement some of the
   // runtime's functionality.
   if (hasExportSymbolDirective(Args)) {
-    addExportedSymbol(CmdArgs, "___llvm_profile_filename");
-    addExportedSymbol(CmdArgs, "___llvm_profile_raw_version");
-    addExportedSymbol(CmdArgs, "_lprofCurFilename");
+    if (needsGCovInstrumentation(Args)) {
+      addExportedSymbol(CmdArgs, "___gcov_flush");
+      addExportedSymbol(CmdArgs, "_flush_fn_list");
+      addExportedSymbol(CmdArgs, "_writeout_fn_list");
+    } else {
+      addExportedSymbol(CmdArgs, "___llvm_profile_filename");
+      addExportedSymbol(CmdArgs, "___llvm_profile_raw_version");
+      addExportedSymbol(CmdArgs, "_lprofCurFilename");
+      addExportedSymbol(CmdArgs, "_lprofMergeValueProfData");
+    }
     addExportedSymbol(CmdArgs, "_lprofDirMode");
-    addExportedSymbol(CmdArgs, "_lprofMergeValueProfData");
   }
 }
 
Index: clang/lib/Driver/ToolChain.cpp
===================================================================
--- clang/lib/Driver/ToolChain.cpp
+++ clang/lib/Driver/ToolChain.cpp
@@ -403,19 +403,23 @@
 }
 
 bool ToolChain::needsProfileRT(const ArgList &Args) {
-  if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
-                   false) ||
+  if (needsGCovInstrumentation(Args) ||
       Args.hasArg(options::OPT_fprofile_generate) ||
       Args.hasArg(options::OPT_fprofile_generate_EQ) ||
       Args.hasArg(options::OPT_fprofile_instr_generate) ||
       Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
-      Args.hasArg(options::OPT_fcreate_profile) ||
-      Args.hasArg(options::OPT_coverage))
+      Args.hasArg(options::OPT_fcreate_profile))
     return true;
 
   return false;
 }
 
+bool ToolChain::needsGCovInstrumentation(const llvm::opt::ArgList &Args) {
+  return Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
+                      false) ||
+         Args.hasArg(options::OPT_coverage);
+}
+
 Tool *ToolChain::SelectTool(const JobAction &JA) const {
   if (getDriver().ShouldUseClangCompiler(JA)) return getClang();
   Action::ActionClass AC = JA.getKind();
Index: clang/include/clang/Driver/ToolChain.h
===================================================================
--- clang/include/clang/Driver/ToolChain.h
+++ clang/include/clang/Driver/ToolChain.h
@@ -381,6 +381,9 @@
   /// needsProfileRT - returns true if instrumentation profile is on.
   static bool needsProfileRT(const llvm::opt::ArgList &Args);
 
+  /// Returns true if gcov instrumentation (-fprofile-arcs or --coverage) is on.
+  static bool needsGCovInstrumentation(const llvm::opt::ArgList &Args);
+
   /// IsUnwindTablesDefault - Does this tool chain use -funwind-tables
   /// by default.
   virtual bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to