Merge pull request #98 from gregestren:master

PiperOrigin-RevId: 366213902
Change-Id: I25281d0487aa1b66b3c81db0fbd723ce3640a49b
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml
index f227fc0..680f7c2 100644
--- a/.bazelci/presubmit.yml
+++ b/.bazelci/presubmit.yml
@@ -48,15 +48,19 @@
     <<: *common
   examples:
     platform: ubuntu1804
-    bazel: last_downstream_green
+    bazel: last_green
     build_targets:
     - "//examples/test_cc_shared_library/..."
+    - "//examples/test_cc_shared_library/diamond_inheritance/..."
     build_flags:
     - "--experimental_cc_shared_library"
     - "--//examples:incompatible_link_once=True"
+    - "--//examples:enable_permissions_check=True"
     test_flags:
     - "--test_timeout=120"
     - "--experimental_cc_shared_library"
     - "--//examples:incompatible_link_once=True"
+    - "--//examples:enable_permissions_check=True"
     test_targets:
     - "//examples/test_cc_shared_library/..."
+    - "//examples/test_cc_shared_library/diamond_inheritance/..."
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..cb5854b
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,9 @@
+# This the official list of authors for copyright purposes.
+# This file is distinct from the CONTRIBUTORS files.
+# See the latter for an explanation.
+
+# Names should be added to this file as:
+# Name or Organization <email address>
+# The email address is not required for organizations.
+
+Google Inc.
diff --git a/cc/find_cc_toolchain.bzl b/cc/find_cc_toolchain.bzl
index b0c3935..463e79a 100644
--- a/cc/find_cc_toolchain.bzl
+++ b/cc/find_cc_toolchain.bzl
@@ -40,7 +40,7 @@
     foo = rule(
         implementation = _foo_impl,
         toolchains = [
-            "@rules_cc//cc:toolchain_type", # copybara-use-repo-external-label
+            "@bazel_tools//tools/cpp:toolchain_type", # copybara-use-repo-external-label
         ],
     )
 
@@ -63,9 +63,12 @@
 
     # Check the incompatible flag for toolchain resolution.
     if hasattr(cc_common, "is_cc_toolchain_resolution_enabled_do_not_use") and cc_common.is_cc_toolchain_resolution_enabled_do_not_use(ctx = ctx):
-        if "//cc:toolchain_type" in ctx.toolchains:
-            return ctx.toolchains["//cc:toolchain_type"]
-        fail("In order to use find_cc_toolchain, your rule has to depend on C++ toolchain. See find_cc_toolchain.bzl docs for details.")
+        if not "@bazel_tools//tools/cpp:toolchain_type" in ctx.toolchains:  # copybara-use-repo-external-label
+            fail("In order to use find_cc_toolchain, your rule has to depend on C++ toolchain. See find_cc_toolchain.bzl docs for details.")
+        toolchain_info = ctx.toolchains["@bazel_tools//tools/cpp:toolchain_type"]  # copybara-use-repo-external-label
+        if hasattr(toolchain_info, "cc_provider_in_toolchain") and hasattr(toolchain_info, "cc"):
+            return toolchain_info.cc
+        return toolchain_info
 
     # Fall back to the legacy implicit attribute lookup.
     if hasattr(ctx.attr, "_cc_toolchain"):
diff --git a/cc/private/rules_impl/cc_flags_supplier.bzl b/cc/private/rules_impl/cc_flags_supplier.bzl
index 252103c..f15f1c2 100644
--- a/cc/private/rules_impl/cc_flags_supplier.bzl
+++ b/cc/private/rules_impl/cc_flags_supplier.bzl
@@ -30,7 +30,7 @@
     attrs = {
         "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
     },
-    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
+    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],  # copybara-use-repo-external-label
     incompatible_use_toolchain_transition = True,
     fragments = ["cpp"],
 )
diff --git a/cc/private/rules_impl/compiler_flag.bzl b/cc/private/rules_impl/compiler_flag.bzl
index 4a59a03..ef08599 100644
--- a/cc/private/rules_impl/compiler_flag.bzl
+++ b/cc/private/rules_impl/compiler_flag.bzl
@@ -26,6 +26,7 @@
         "_cc_toolchain": attr.label(default = Label("//cc:current_cc_toolchain")),
     },
     toolchains = [
-        "@rules_cc//cc:toolchain_type",  # copybara-use-repo-external-label
+        "@bazel_tools//tools/cpp:toolchain_type",  # copybara-use-repo-external-label
     ],
+    incompatible_use_toolchain_transition = True,
 )
diff --git a/examples/BUILD b/examples/BUILD
index c770074..c7da75d 100644
--- a/examples/BUILD
+++ b/examples/BUILD
@@ -25,6 +25,12 @@
 )
 
 bool_flag(
+    name = "enable_permissions_check",
+    build_setting_default = False,
+    visibility = ["//visibility:public"],
+)
+
+bool_flag(
     name = "experimental_debug",
     build_setting_default = False,
     visibility = ["//visibility:public"],
diff --git a/examples/experimental_cc_shared_library.bzl b/examples/experimental_cc_shared_library.bzl
index acda49f..905bd27 100644
--- a/examples/experimental_cc_shared_library.bzl
+++ b/examples/experimental_cc_shared_library.bzl
@@ -109,7 +109,7 @@
             if export in exports_map:
                 fail("Two shared libraries in dependencies export the same symbols. Both " +
                      exports_map[export].libraries[0].dynamic_library.short_path +
-                     " and " + linker_input.dynamic_library.short_path +
+                     " and " + linker_input.libraries[0].dynamic_library.short_path +
                      " export " + export)
             exports_map[export] = linker_input
     return exports_map
@@ -162,6 +162,9 @@
     return pattern.package == value.package and pattern.name == value.name
 
 def _check_if_target_can_be_exported(target, current_label, permissions):
+    if permissions == None:
+        return True
+
     if (target.workspace_name != current_label.workspace_name or
         _same_package_or_above(current_label, target)):
         return True
@@ -271,7 +274,7 @@
                     linker_input.owner,
                     ctx.label,
                     ctx.attr.exports_filter,
-                    ctx.attr.permissions,
+                    _get_permissions(ctx),
                 ):
                     exports[owner] = True
                     can_be_linked_statically = True
@@ -301,6 +304,11 @@
 
     return True
 
+def _get_permissions(ctx):
+    if ctx.attr._enable_permissions_check[BuildSettingInfo].value:
+        return ctx.attr.permissions
+    return None
+
 def _cc_shared_library_impl(ctx):
     cc_common.check_experimental_cc_shared_library()
     cc_toolchain = find_cc_toolchain(ctx)
@@ -318,7 +326,7 @@
             fail("Trying to export a library already exported by a different shared library: " +
                  str(export.label))
 
-        _check_if_target_should_be_exported_without_filter(export.label, ctx.label, ctx.attr.permissions)
+        _check_if_target_should_be_exported_without_filter(export.label, ctx.label, _get_permissions(ctx))
 
     preloaded_deps_direct_labels = {}
     preloaded_dep_merged_cc_info = None
@@ -457,11 +465,13 @@
         "static_deps": attr.string_list(),
         "user_link_flags": attr.string_list(),
         "_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"),
+        "_enable_permissions_check": attr.label(default = "//examples:enable_permissions_check"),
         "_experimental_debug": attr.label(default = "//examples:experimental_debug"),
         "_incompatible_link_once": attr.label(default = "//examples:incompatible_link_once"),
     },
-    toolchains = ["@rules_cc//cc:toolchain_type"],  # copybara-use-repo-external-label
+    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],  # copybara-use-repo-external-label
     fragments = ["cpp"],
+    incompatible_use_toolchain_transition = True,
 )
 
 for_testing_dont_use_check_if_target_under_path = _check_if_target_under_path
diff --git a/examples/my_c_archive/my_c_archive.bzl b/examples/my_c_archive/my_c_archive.bzl
index 86cebe9..b4138af 100644
--- a/examples/my_c_archive/my_c_archive.bzl
+++ b/examples/my_c_archive/my_c_archive.bzl
@@ -95,6 +95,6 @@
         "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
     },
     fragments = ["cpp"],
-    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
+    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],  # copybara-use-repo-external-label
     incompatible_use_toolchain_transition = True,
 )
diff --git a/examples/my_c_compile/my_c_compile.bzl b/examples/my_c_compile/my_c_compile.bzl
index edb839c..f29207e 100644
--- a/examples/my_c_compile/my_c_compile.bzl
+++ b/examples/my_c_compile/my_c_compile.bzl
@@ -76,7 +76,7 @@
         "src": attr.label(mandatory = True, allow_single_file = True),
         "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
     },
-    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
+    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],  # copybara-use-repo-external-label
     incompatible_use_toolchain_transition = True,
     fragments = ["cpp"],
 )
diff --git a/examples/test_cc_shared_library/BUILD b/examples/test_cc_shared_library/BUILD
index 5f3d03b..16ce79e 100644
--- a/examples/test_cc_shared_library/BUILD
+++ b/examples/test_cc_shared_library/BUILD
@@ -1,6 +1,6 @@
 load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
 load("//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
-load("//examples:experimental_cc_shared_library.bzl", "LINKABLE_MORE_THAN_ONCE", "cc_shared_library")
+load("//examples:experimental_cc_shared_library.bzl", "LINKABLE_MORE_THAN_ONCE", "cc_shared_library", "cc_shared_library_permissions")
 load(":starlark_tests.bzl", "additional_inputs_test", "build_failure_test", "linking_suffix_test", "paths_test")
 
 package(
@@ -21,6 +21,16 @@
     deps = ["foo"],
 )
 
+cc_binary(
+    name = "binary_with_bar_so_twice",
+    srcs = ["main.cc"],
+    dynamic_deps = [
+        "foo_so",
+        "bar_so",
+    ],
+    deps = ["foo"],
+)
+
 cc_shared_library(
     name = "foo_so",
     additional_linker_inputs = [
@@ -202,3 +212,25 @@
     srcs = ["starlark_tests.bzl"],
     visibility = ["//visibility:private"],
 )
+
+cc_shared_library_permissions(
+    name = "permissions",
+    targets = [
+        "//examples/test_cc_shared_library:a_suffix",
+        "//examples/test_cc_shared_library:qux",
+        "//examples/test_cc_shared_library:qux2",
+    ],
+    visibility = ["//examples/test_cc_shared_library/diamond_inheritance:__pkg__"],
+)
+
+build_failure_test(
+    name = "two_dynamic_deps_same_export_in_so_test",
+    message = "Two shared libraries in dependencies export the same symbols",
+    target_under_test = "//examples/test_cc_shared_library/failing_targets:two_dynamic_deps_same_export_in_so",
+)
+
+build_failure_test(
+    name = "two_dynamic_deps_same_export_in_binary_test",
+    message = "Two shared libraries in dependencies export the same symbols",
+    target_under_test = "//examples/test_cc_shared_library/failing_targets:two_dynamic_deps_same_export_in_binary",
+)
diff --git a/examples/test_cc_shared_library/diamond_inheritance/BUILD b/examples/test_cc_shared_library/diamond_inheritance/BUILD
new file mode 100644
index 0000000..7b83574
--- /dev/null
+++ b/examples/test_cc_shared_library/diamond_inheritance/BUILD
@@ -0,0 +1,40 @@
+load("//cc:defs.bzl", "cc_binary")
+load("//examples:experimental_cc_shared_library.bzl", "cc_shared_library")
+
+cc_shared_library(
+    name = "baz_so",
+    permissions = [
+        "//examples/test_cc_shared_library:permissions",
+    ],
+    roots = ["//examples/test_cc_shared_library:a_suffix"],
+)
+
+cc_shared_library(
+    name = "qux_so",
+    dynamic_deps = [":baz_so"],
+    permissions = [
+        "//examples/test_cc_shared_library:permissions",
+    ],
+    roots = ["//examples/test_cc_shared_library:qux"],
+)
+
+cc_shared_library(
+    name = "qux2_so",
+    dynamic_deps = [":baz_so"],
+    permissions = [
+        "//examples/test_cc_shared_library:permissions",
+    ],
+    roots = ["//examples/test_cc_shared_library:qux2"],
+)
+
+cc_binary(
+    name = "diamond_inheritance",
+    srcs = ["main.cc"],
+    dynamic_deps = [
+        ":qux_so",
+        ":qux2_so",
+    ],
+    deps = [
+        "//examples/test_cc_shared_library:a_suffix",
+    ],
+)
diff --git a/examples/test_cc_shared_library/diamond_inheritance/main.cc b/examples/test_cc_shared_library/diamond_inheritance/main.cc
new file mode 100644
index 0000000..18e4366
--- /dev/null
+++ b/examples/test_cc_shared_library/diamond_inheritance/main.cc
@@ -0,0 +1,8 @@
+#include <iostream>
+
+#include "examples/test_cc_shared_library/a_suffix.h"
+
+int main() {
+  std::cout << "hello " << a_suffix() << std::endl;
+  return 0;
+}
diff --git a/examples/test_cc_shared_library/failing_targets/BUILD b/examples/test_cc_shared_library/failing_targets/BUILD
index 16e4b47..f0bf796 100644
--- a/examples/test_cc_shared_library/failing_targets/BUILD
+++ b/examples/test_cc_shared_library/failing_targets/BUILD
@@ -1,4 +1,4 @@
-load("//cc:defs.bzl", "cc_binary")
+load("//cc:defs.bzl", "cc_binary", "cc_library")
 load("//examples:experimental_cc_shared_library.bzl", "cc_shared_library", "cc_shared_library_permissions")
 
 package(
@@ -35,3 +35,56 @@
         "//examples/test_cc_shared_library:foo",
     ],
 )
+
+cc_library(
+    name = "a",
+    srcs = ["a.cc"],
+)
+
+cc_library(
+    name = "b",
+    srcs = ["b.cc"],
+)
+
+cc_library(
+    name = "c",
+    srcs = ["c.cc"],
+)
+
+cc_shared_library(
+    name = "two_dynamic_deps_same_export_in_so",
+    dynamic_deps = [
+        ":b_so",
+        ":b2_so",
+    ],
+    roots = [
+        ":a",
+    ],
+    tags = TAGS,
+)
+
+cc_binary(
+    name = "two_dynamic_deps_same_export_in_binary",
+    srcs = ["main.cc"],
+    dynamic_deps = [
+        ":b_so",
+        ":b2_so",
+    ],
+    tags = TAGS,
+)
+
+cc_shared_library(
+    name = "b_so",
+    roots = [
+        ":b",
+    ],
+    tags = TAGS,
+)
+
+cc_shared_library(
+    name = "b2_so",
+    roots = [
+        ":b",
+    ],
+    tags = TAGS,
+)
diff --git a/examples/test_cc_shared_library/failing_targets/a.cc b/examples/test_cc_shared_library/failing_targets/a.cc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/examples/test_cc_shared_library/failing_targets/a.cc
diff --git a/examples/test_cc_shared_library/failing_targets/b.cc b/examples/test_cc_shared_library/failing_targets/b.cc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/examples/test_cc_shared_library/failing_targets/b.cc
diff --git a/examples/test_cc_shared_library/failing_targets/c.cc b/examples/test_cc_shared_library/failing_targets/c.cc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/examples/test_cc_shared_library/failing_targets/c.cc
diff --git a/examples/test_cc_shared_library/failing_targets/main.cc b/examples/test_cc_shared_library/failing_targets/main.cc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/examples/test_cc_shared_library/failing_targets/main.cc
diff --git a/examples/write_cc_toolchain_cpu/write_cc_toolchain_cpu.bzl b/examples/write_cc_toolchain_cpu/write_cc_toolchain_cpu.bzl
index 7830240..b4e63a3 100644
--- a/examples/write_cc_toolchain_cpu/write_cc_toolchain_cpu.bzl
+++ b/examples/write_cc_toolchain_cpu/write_cc_toolchain_cpu.bzl
@@ -28,6 +28,6 @@
     attrs = {
         "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
     },
-    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
+    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],  # copybara-use-repo-external-label
     incompatible_use_toolchain_transition = True,
 )