intellij icon indicating copy to clipboard operation
intellij copied to clipboard

CLion plugin breaks CLion Nova code analysis for std::string_view

Open erinacio opened this issue 9 months ago • 11 comments

Description of the bug:

After upgraded Bazel plugin from 2025.01.21.0.2, CLion Nova failed to correctly analysis code using std::string_view, saying that it doesn't satisfy many trivial concepts (like copyable, destructible, std.).

Image

This issue happens from any version uploaded after Feb 21, 2025, including a version that somehow named 2024.02.04.01-api-243 despite that it was uploaded in Feb 2025.

Disabling ReSharper engine (i.e. using conventional clangd engine) solves this problem. I have no idea if it's a ReSharper engine bug or a Bazel plugin bug, but since it was triggered by a Bazel plugin update and not a CLion update, I decided to report it here as a Bazel plugin bug.

Which category does this issue belong to?

CLion

What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

  • WORKSPACE
workspace(name = "bzlexp")
  • BUILD.bazel
cc_binary(
    name = "main",
    srcs = ["main.cc"],
)
  • main.cc
#include <string_view>

static_assert(std::copyable<std::string_view>);
static_assert(std::movable<std::string_view>);
static_assert(std::destructible<std::string_view>);

int main() { return 0; }
  • .bazelrc
build:clang_config --crosstool_top=//toolchain:clang_suite
build --cxxopt -std=c++2b
build --cxxopt --stdlib=libc++
build --linkopt -stdlib=libc++
build --linkopt -lc++abi
build --linkopt -lrt
build --linkopt -pthread

Which Intellij IDE are you using? Please provide the specific version.

CLion 2024.3.4

What programming languages and tools are you using? Please provide specific versions.

C++23, clang 17

What Bazel plugin version are you using?

2025.03.04.0.1-api-version-243

Have you found anything relevant by searching the web?

Nope.

Any other information, logs, or outputs that you want to share?

Haven't tried different IDE versions. Only 2024.3.4 was checked.

I exported CC and CXX environment variable before launching the IDE to force Bazel using clang instead of gcc.

erinacio avatar Mar 24 '25 08:03 erinacio

This issue persists after upgraded to 2025.03.18.0.1-api-version-243.

Also some new discovery. I tried using system clang instead of my self-built clang and it seems to work. However, <string> resolves to the file in libstdc++ despite that I specified -stdlib=libc++ in --cxxopt and --linkopt in .bazelrc. This would be problematic as libstdc++ and libc++ are not identical. I can see /usr/include/c++/v1 in header search path list in "compiler info", however it only appears after libstdc++ include path. This might have no relationship with the original issue, but still looks interesting. This didn't appear in my original case because the clang I self-built is sysroot-ed, and that sysroot doesn't contain libstdc++.

erinacio avatar Apr 03 '25 06:04 erinacio

@erinacio well this happens with crosstool thing. can't you update to platforms and tell us whether the issue is reproducible there?

ujohnny avatar Apr 10 '25 12:04 ujohnny

@erinacio well this happens with crosstool thing. can't you update to platforms and tell us whether the issue is reproducible there?

That's not trivial task for me.... I have never attempted to use bazel platforms or toolchains and the official documentation looks confusing to me. At least bazel build works without extra work, so it might not be weird for others to expect bazel plugin works under the same condition. I may try to understand how bazel platforms and toolchains work and see if the plugin still breaks when I have spare time, but not now.

Also, may I have a basic explanation why this didn't break with older versions but breaks now? What has changed in the plugin?

erinacio avatar Apr 10 '25 12:04 erinacio

Also, may I have a basic explanation why this didn't break with older versions but breaks now? What has changed in the plugin?

we did some changes to toolchain support recently and also given that crosstool_top is deprecated I'm a bit suspicious about this overall. can you share the definition of cc_toolchain and other related things from clang_suite?

ujohnny avatar Apr 10 '25 17:04 ujohnny

Also, may I have a basic explanation why this didn't break with older versions but breaks now? What has changed in the plugin?

we did some changes to toolchain support recently and also given that crosstool_top is deprecated I'm a bit suspicious about this overall. can you share the definition of cc_toolchain and other related things from clang_suite?

We have neither cc_toolchain nor clang_suite in any file in our repository. For now we simply export CC=/path/to/llvm/bin/clang CXX=/path/to/llvm/bin/clang++ for development and build.

I did find something indicating cc_toolchain in external packages but none of them has literal clang_suite in the code. The most interesting reference appears in bazel-<repo_name>/external/local_config_cc/BUILD:

@local_config_cc//:BUILD
# Copyright 2016 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This becomes the BUILD file for @local_config_cc// under non-BSD unixes.
load(":cc_toolchain_config.bzl", "cc_toolchain_config")
load(":armeabi_cc_toolchain_config.bzl", "armeabi_cc_toolchain_config")
load("@rules_cc//cc:defs.bzl", "cc_toolchain", "cc_toolchain_suite")
package(default_visibility = ["//visibility:public"])
licenses(["notice"])  # Apache 2.0
cc_library(
    name = "malloc",
)
filegroup(
    name = "empty",
    srcs = [],
)
filegroup(
    name = "cc_wrapper",
    srcs = ["cc_wrapper.sh"],
)
filegroup(
    name = "compiler_deps",
    srcs = glob(["extra_tools/**"], allow_empty = True) + [":builtin_include_directory_paths"],
)
# This is the entry point for --crosstool_top.  Toolchains are found
# by lopping off the name of --crosstool_top and searching for
# the "${CPU}" entry in the toolchains attribute.
cc_toolchain_suite(
    name = "toolchain",
    toolchains = {
        "k8|clang": ":cc-compiler-k8",
        "k8": ":cc-compiler-k8",
        "armeabi-v7a|compiler": ":cc-compiler-armeabi-v7a",
        "armeabi-v7a": ":cc-compiler-armeabi-v7a",
    },
)
cc_toolchain(
    name = "cc-compiler-k8",
    toolchain_identifier = "local",
    toolchain_config = ":local",
    all_files = ":compiler_deps",
    ar_files = ":compiler_deps",
    as_files = ":compiler_deps",
    compiler_files = ":compiler_deps",
    dwp_files = ":empty",
    linker_files = ":compiler_deps",
    objcopy_files = ":empty",
    strip_files = ":empty",
    supports_param_files = 1,
    module_map = ":module.modulemap",
)
cc_toolchain_config(
    name = "local",
    cpu = "k8",
    compiler = "clang",
    toolchain_identifier = "local",
    host_system_name = "local",
    target_system_name = "local",
    target_libc = "local",
    abi_version = "local",
    abi_libc_version = "local",
    cxx_builtin_include_directories = ["/opt/llvm17/lib/clang/17/include",
    "/opt/llvm17/include",
    "/opt/llvm17/lib/clang/17/share",
    "/opt/llvm17/include/c++/v1"],
    tool_paths = {"ar": "/usr/bin/ar",
        "ld": "/usr/bin/ld",
        "llvm-cov": "/opt/llvm17/bin/llvm-cov",
        "llvm-profdata": "/opt/llvm17/bin/llvm-profdata",
        "cpp": "/usr/bin/cpp",
        "gcc": "/opt/llvm17/bin/clang-17",
        "dwp": "/usr/bin/dwp",
        "gcov": "/usr/bin/gcov",
        "nm": "/usr/bin/nm",
        "objcopy": "/usr/bin/objcopy",
        "objdump": "/usr/bin/objdump",
        "strip": "/usr/bin/strip"},
    compile_flags = ["-fstack-protector",
    "-Wall",
    "-Wthread-safety",
    "-Wself-assign",
    "-Wunused-but-set-parameter",
    "-Wno-free-nonheap-object",
    "-fcolor-diagnostics",
    "-fno-omit-frame-pointer"],
    opt_compile_flags = ["-g0",
    "-O2",
    "-D_FORTIFY_SOURCE=1",
    "-DNDEBUG",
    "-ffunction-sections",
    "-fdata-sections"],
    dbg_compile_flags = ["-g"],
    cxx_flags = ["-std=c++0x"],
    link_flags = ["-fuse-ld=/opt/llvm17/bin/ld.lld",
    "-Wl,-no-as-needed",
    "-Wl,-z,relro,-z,now",
    "-B/opt/llvm17/bin"],
    link_libs = ["-lstdc++",
    "-lm"],
    opt_link_flags = ["-Wl,--gc-sections"],
    unfiltered_compile_flags = ["-no-canonical-prefixes",
    "-Wno-builtin-macro-redefined",
    "-D__DATE__=\"redacted\"",
    "-D__TIMESTAMP__=\"redacted\"",
    "-D__TIME__=\"redacted\""],
    coverage_compile_flags = ["--coverage"],
    coverage_link_flags = ["--coverage"],
    supports_start_end_lib = True,
)
# Android tooling requires a default toolchain for the armeabi-v7a cpu.
cc_toolchain(
    name = "cc-compiler-armeabi-v7a",
    toolchain_identifier = "stub_armeabi-v7a",
    toolchain_config = ":stub_armeabi-v7a",
    all_files = ":empty",
    ar_files = ":empty",
    as_files = ":empty",
    compiler_files = ":empty",
    dwp_files = ":empty",
    linker_files = ":empty",
    objcopy_files = ":empty",
    strip_files = ":empty",
    supports_param_files = 1,
)
armeabi_cc_toolchain_config(name = "stub_armeabi-v7a")

This file seems to be generated by (possibly) rules_cc bundled in bazel 6.2.0 as a sum up of the environment it detected.

erinacio avatar Apr 11 '25 06:04 erinacio

The issue still persists after upgraded to CLion 2025.1 and Bazel plugin 2025.04.01.0.1-api-version-251.

erinacio avatar Apr 17 '25 06:04 erinacio

@erinacio I'll follow up on this soon. We're just were a little bit busy with regressions came to us from AOSP.

ujohnny avatar Apr 17 '25 06:04 ujohnny

As far as I can tell the reason why /usr/include/c++/v1 (libc++) is listed after /usr/include/c++/14 (libstdc++) in the include paths, is because that's the way Bazel reports it. If you run

USE_BAZEL_VERSION=7.5.  bazel cquery @bazel_tools//tools/cpp:current_cc_toolchain  --output=starlark --starlark:expr="providers(target)['CcToolchainInfo'].built_in_include_directories"

I get the following output on your example project:

["/usr/lib/clang/19/include", "/usr/local/include", "/usr/include", "/usr/lib/clang/19/share", "/usr/include/c++/14", "/usr/include/c++/14/x86_64-redhat-linux", "/usr/include/c++/14/backward", "/usr/include/c++/v1", "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"]

Thus, I think it was caused by this PR since here we start forwarding builtin includes to CLion.

We can maybe put this change behind a registry key?

LeFrosch avatar Apr 22 '25 15:04 LeFrosch

This is interesting. Besides of plugin maintainers investigating this issue, I will also do some investigation on my side.

Currently I'm busy with work. When I become vacant I would:

  • Create a build script that builds the clang I use. I tweaked many default settings like changing the default rt to compiler-rt, default stdlib to libc++, and using an ELF interpreter at a different location. The current binary I use now is a handcrafted one without proper reproducible build scripts. This may help others reproducing this same issue.
  • Have a better understand about how bazel toolchain works. Potentially also figure out why we always see a suspicious -std=c++0x even we specified -std=c++20 (are we using bazel wrong?). Fortunately the later always take precedence so no build issue (for now).
  • Try if properly telling bazel to use clang (instead of export CC, which I believe bazel doesn't like this) would make this issue disappear.

This is likely to happen near the end of this Q.

erinacio avatar Apr 24 '25 06:04 erinacio

I did some further research and builtin includes are resolved here: https://github.com/bazelbuild/rules_cc/blob/3dce172deec2a4563c28eae02a8bb18555abafb2/cc/private/toolchain/unix_cc_configure.bzl#L550

I think this is quite similar to our compiler info collection @ujohnny: https://github.com/bazelbuild/rules_cc/blob/3dce172deec2a4563c28eae02a8bb18555abafb2/cc/private/toolchain/unix_cc_configure.bzl#L113

Also it seems they are only looking at the environment variable to derive CXX flags and ignore the fragment, looks like a bug to me: https://github.com/bazelbuild/rules_cc/blob/3dce172deec2a4563c28eae02a8bb18555abafb2/cc/private/toolchain/unix_cc_configure.bzl#L469

But fragments are not available in repository rules, sooo idk how to continue with this.

LeFrosch avatar Jun 12 '25 13:06 LeFrosch

https://github.com/bazelbuild/rules_cc/issues/418

LeFrosch avatar Jun 12 '25 13:06 LeFrosch

Hi @erinacio we just merged #7667. Could you try your project with these changes if this lands in beta (or build master if you like). This tries to work around the rules_cc issue.

LeFrosch avatar Jul 11 '25 12:07 LeFrosch

Hi @erinacio we just merged #7667. Could you try your project with these changes if this lands in beta (or build master if you like). This tries to work around the rules_cc issue.

I built the plugin's master branch (and upgraded CLion to EAP as I can't figure out how to build this plugin for CLion 2025.1). Can confirm it works. Works on both the small test project and the real full scale project.

erinacio avatar Jul 11 '25 13:07 erinacio