mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-25 09:20:12 +01:00
Bumps the npm_and_yarn group with 2 updates in the /utils/vscode directory: [brace-expansion](https://github.com/juliangruber/brace-expansion) and [picomatch](https://github.com/micromatch/picomatch). Updates `brace-expansion` from 1.1.12 to 1.1.14 <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/juliangruber/brace-expansion/commit/10c05fcf3699b1a29ef5e611c011af3d3c97e6e3"><code>10c05fc</code></a> 1.1.14</li> <li><a href="https://github.com/juliangruber/brace-expansion/commit/1afa1b22ead12f6a7a02f25bf0f7d64c2439b007"><code>1afa1b2</code></a> Add opt-in { max } mitigation to v1 legacy line (<a href="https://redirect.github.com/juliangruber/brace-expansion/issues/103">#103</a>)</li> <li><a href="https://github.com/juliangruber/brace-expansion/commit/2fbb6a2aa0f984bb2fb5f60252ca6cba3e1368ec"><code>2fbb6a2</code></a> Revert "Backport fix for GHSA-7h2j-956f-4vf2 to v1 (<a href="https://redirect.github.com/juliangruber/brace-expansion/issues/101">#101</a>)" (<a href="https://redirect.github.com/juliangruber/brace-expansion/issues/102">#102</a>)</li> <li><a href="https://github.com/juliangruber/brace-expansion/commit/0d7652e3093d3273151729812f9b0b79a17ecba6"><code>0d7652e</code></a> Backport fix for GHSA-7h2j-956f-4vf2 to v1 (<a href="https://redirect.github.com/juliangruber/brace-expansion/issues/101">#101</a>)</li> <li><a href="https://github.com/juliangruber/brace-expansion/commit/6c353caf23beb9644f858eb3fe38d43a68b82898"><code>6c353ca</code></a> 1.1.13</li> <li><a href="https://github.com/juliangruber/brace-expansion/commit/7fd684f89fdde3549563d0a6522226a9189472a2"><code>7fd684f</code></a> Backport fix for GHSA-f886-m6hf-6m8v (<a href="https://redirect.github.com/juliangruber/brace-expansion/issues/95">#95</a>)</li> <li>See full diff in <a href="https://github.com/juliangruber/brace-expansion/compare/v1.1.12...v1.1.14">compare view</a></li> </ul> </details> <br /> Updates `picomatch` from 4.0.3 to 4.0.4 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/micromatch/picomatch/releases">picomatch's releases</a>.</em></p> <blockquote> <h2>4.0.4</h2> <p>This is a security release fixing several security relevant issues.</p> <h2>What's Changed</h2> <ul> <li>Fix for <a href="https://github.com/micromatch/picomatch/security/advisories/GHSA-c2c7-rcm5-vvqj">CVE-2026-33671</a></li> <li>Fix for <a href="https://github.com/micromatch/picomatch/security/advisories/GHSA-3v7f-55p6-f55p">CVE-2026-33672</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4">https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/micromatch/picomatch/commit/e5474fc1a4d7991870058170407dda8a42be5334"><code>e5474fc</code></a> Publish 4.0.4</li> <li><a href="https://github.com/micromatch/picomatch/commit/4516eb521f13a46b2fe1a1d2c9ef6b20ddc0e903"><code>4516eb5</code></a> Merge commit from fork</li> <li><a href="https://github.com/micromatch/picomatch/commit/5eceecd27543b8e056b9307d69e105ea03618a7d"><code>5eceecd</code></a> Merge commit from fork</li> <li><a href="https://github.com/micromatch/picomatch/commit/0db7dd70651ca7c8265601c0442a996ed32e3238"><code>0db7dd7</code></a> Run benchmark again against latest minimatch version (<a href="https://redirect.github.com/micromatch/picomatch/issues/161">#161</a>)</li> <li><a href="https://github.com/micromatch/picomatch/commit/95003777eb1c60dec09495a8231fa2ba4054d76a"><code>9500377</code></a> docs: clarify what brace expansion syntax is and isn't supported (<a href="https://redirect.github.com/micromatch/picomatch/issues/134">#134</a>)</li> <li><a href="https://github.com/micromatch/picomatch/commit/2661f23eca86c8b4a2b14815b9b2b3b74bd5a171"><code>2661f23</code></a> fix typo in globstars.js test name (<a href="https://redirect.github.com/micromatch/picomatch/issues/138">#138</a>)</li> <li><a href="https://github.com/micromatch/picomatch/commit/1798b07e9df59500b9cf567294d44d559032f4c7"><code>1798b07</code></a> docs: fix <code>makeRe</code> example (<a href="https://redirect.github.com/micromatch/picomatch/issues/143">#143</a>)</li> <li><a href="https://github.com/micromatch/picomatch/commit/9d76bc57a03b7f57cc4ca516c8071daf632bafd8"><code>9d76bc5</code></a> chore: undocument removed options (<a href="https://redirect.github.com/micromatch/picomatch/issues/146">#146</a>)</li> <li><a href="https://github.com/micromatch/picomatch/commit/e4d718bbfb47e4f030ab2612b5b04a9297fe272d"><code>e4d718b</code></a> Remove unused time-require (<a href="https://redirect.github.com/micromatch/picomatch/issues/160">#160</a>)</li> <li><a href="https://github.com/micromatch/picomatch/commit/38dffeb16221cc8eb8981524fb6895dd2aaaba76"><code>38dffeb</code></a> chore(deps): pin dependencies (<a href="https://redirect.github.com/micromatch/picomatch/issues/158">#158</a>)</li> <li>Additional commits viewable in <a href="https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4">compare view</a></li> </ul> </details> <br /> Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/carbon-language/carbon-lang/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
257 lines
9.6 KiB
C++
257 lines
9.6 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#include "toolchain/check/cpp/impl_lookup.h"
|
|
|
|
#include "clang/Sema/Sema.h"
|
|
#include "toolchain/base/kind_switch.h"
|
|
#include "toolchain/check/cpp/import.h"
|
|
#include "toolchain/check/cpp/location.h"
|
|
#include "toolchain/check/cpp/overload_resolution.h"
|
|
#include "toolchain/check/custom_witness.h"
|
|
#include "toolchain/check/impl.h"
|
|
#include "toolchain/check/impl_lookup.h"
|
|
#include "toolchain/check/import_ref.h"
|
|
#include "toolchain/check/inst.h"
|
|
#include "toolchain/check/type.h"
|
|
#include "toolchain/sem_ir/builtin_function_kind.h"
|
|
#include "toolchain/sem_ir/ids.h"
|
|
#include "toolchain/sem_ir/typed_insts.h"
|
|
|
|
namespace Carbon::Check {
|
|
|
|
// Given a type constant, return the corresponding class scope if there is one.
|
|
static auto GetClassScope(Context& context,
|
|
SemIR::ConstantId query_self_const_id)
|
|
-> SemIR::NameScopeId {
|
|
auto class_type = context.constant_values().TryGetInstAs<SemIR::ClassType>(
|
|
query_self_const_id);
|
|
if (!class_type) {
|
|
// Not a class.
|
|
return SemIR::NameScopeId::None;
|
|
}
|
|
|
|
return context.classes().Get(class_type->class_id).scope_id;
|
|
}
|
|
|
|
// If the given type is a C++ tag (class or enumeration) type, returns the
|
|
// corresponding tag declaration. Otherwise returns nullptr.
|
|
// TODO: Handle qualified types.
|
|
static auto TypeAsTagDecl(Context& context,
|
|
SemIR::ConstantId query_self_const_id)
|
|
-> clang::TagDecl* {
|
|
SemIR::NameScopeId class_scope_id =
|
|
GetClassScope(context, query_self_const_id);
|
|
if (!class_scope_id.has_value()) {
|
|
return nullptr;
|
|
}
|
|
|
|
const auto& scope = context.name_scopes().Get(class_scope_id);
|
|
auto decl_id = scope.clang_decl_context_id();
|
|
if (!decl_id.has_value()) {
|
|
return nullptr;
|
|
}
|
|
|
|
return dyn_cast<clang::TagDecl>(context.clang_decls().Get(decl_id).key.decl);
|
|
}
|
|
|
|
// If the given type is a C++ class type, returns the corresponding class
|
|
// declaration. Otherwise returns nullptr.
|
|
static auto TypeAsClassDecl(Context& context,
|
|
SemIR::ConstantId query_self_const_id)
|
|
-> clang::CXXRecordDecl* {
|
|
return dyn_cast_or_null<clang::CXXRecordDecl>(
|
|
TypeAsTagDecl(context, query_self_const_id));
|
|
}
|
|
|
|
namespace {
|
|
struct DeclInfo {
|
|
// If null, no C++ decl was found and no witness can be created.
|
|
clang::NamedDecl* decl = nullptr;
|
|
SemIR::ClangDeclKey::Signature signature;
|
|
};
|
|
} // namespace
|
|
|
|
// Finds the InstId for the C++ function that is called by a specific interface.
|
|
// Returns SemIR::InstId::None if a C++ function is not found, and
|
|
// SemIR::ErrorInst::InstId if an error occurs.
|
|
static auto GetFunctionId(Context& context, SemIR::LocId loc_id,
|
|
DeclInfo decl_info) -> SemIR::InstId {
|
|
if (!decl_info.decl) {
|
|
// The C++ type is not able to implement the interface.
|
|
return SemIR::InstId::None;
|
|
}
|
|
|
|
auto* cpp_fn = cast<clang::FunctionDecl>(decl_info.decl);
|
|
|
|
if (context.clang_sema().DiagnoseUseOfOverloadedDecl(
|
|
cpp_fn, GetCppLocation(context, loc_id))) {
|
|
return SemIR::ErrorInst::InstId;
|
|
}
|
|
|
|
auto fn_id =
|
|
ImportCppFunctionDecl(context, loc_id, cpp_fn, decl_info.signature);
|
|
if (fn_id == SemIR::ErrorInst::InstId) {
|
|
return SemIR::ErrorInst::InstId;
|
|
}
|
|
CheckCppOverloadAccess(
|
|
context, loc_id, clang::DeclAccessPair::make(cpp_fn, cpp_fn->getAccess()),
|
|
context.insts().GetAsKnownInstId<SemIR::FunctionDecl>(fn_id));
|
|
|
|
return fn_id;
|
|
}
|
|
|
|
static auto BuildCopyWitness(
|
|
Context& context, SemIR::LocId loc_id,
|
|
SemIR::ConstantId query_self_const_id,
|
|
SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId {
|
|
auto& clang_sema = context.clang_sema();
|
|
|
|
auto* tag_decl = TypeAsTagDecl(context, query_self_const_id);
|
|
if (!tag_decl) {
|
|
return SemIR::InstId::None;
|
|
}
|
|
if (auto* class_decl = dyn_cast<clang::CXXRecordDecl>(tag_decl)) {
|
|
auto decl_info = DeclInfo{.decl = clang_sema.LookupCopyingConstructor(
|
|
class_decl, clang::Qualifiers::Const),
|
|
.signature = {.num_params = 1}};
|
|
auto fn_id = GetFunctionId(context, loc_id, decl_info);
|
|
if (fn_id == SemIR::ErrorInst::InstId || fn_id == SemIR::InstId::None) {
|
|
return fn_id;
|
|
}
|
|
return BuildCustomWitness(context, loc_id, query_self_const_id,
|
|
query_specific_interface_id, {fn_id});
|
|
}
|
|
// Otherwise it's an enum (or eventually a C struct type). Perform a primitive
|
|
// copy.
|
|
return BuildPrimitiveCopyWitness(
|
|
context, loc_id, GetClassScope(context, query_self_const_id),
|
|
query_self_const_id, query_specific_interface_id);
|
|
}
|
|
|
|
static auto BuildCppUnsafeDerefWitness(
|
|
Context& context, SemIR::LocId loc_id,
|
|
SemIR::ConstantId query_self_const_id,
|
|
SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId {
|
|
auto& clang_sema = context.clang_sema();
|
|
|
|
auto* class_decl = TypeAsClassDecl(context, query_self_const_id);
|
|
if (!class_decl) {
|
|
return SemIR::InstId::None;
|
|
}
|
|
auto candidates = class_decl->lookup(
|
|
clang_sema.getASTContext().DeclarationNames.getCXXOperatorName(
|
|
clang::OO_Star));
|
|
if (candidates.empty()) {
|
|
return SemIR::InstId::None;
|
|
}
|
|
if (!candidates.isSingleResult()) {
|
|
context.TODO(loc_id, "operator* overload sets not implemented yet");
|
|
return SemIR::ErrorInst::InstId;
|
|
}
|
|
auto decl_info =
|
|
DeclInfo{.decl = *candidates.begin(), .signature = {.num_params = 0}};
|
|
auto fn_id = GetFunctionId(context, loc_id, decl_info);
|
|
if (fn_id == SemIR::ErrorInst::InstId || fn_id == SemIR::InstId::None) {
|
|
return fn_id;
|
|
}
|
|
|
|
auto result_type_id =
|
|
context.functions()
|
|
.Get(context.insts().GetAs<SemIR::FunctionDecl>(fn_id).function_id)
|
|
.return_type_inst_id;
|
|
if (result_type_id == SemIR::ErrorInst::InstId) {
|
|
return SemIR::ErrorInst::InstId;
|
|
}
|
|
|
|
return BuildCustomWitness(context, loc_id, query_self_const_id,
|
|
query_specific_interface_id,
|
|
{result_type_id, fn_id});
|
|
}
|
|
|
|
static auto BuildDefaultWitness(
|
|
Context& context, SemIR::LocId loc_id,
|
|
SemIR::ConstantId query_self_const_id,
|
|
SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId {
|
|
auto& clang_sema = context.clang_sema();
|
|
|
|
auto* class_decl = TypeAsClassDecl(context, query_self_const_id);
|
|
if (!class_decl) {
|
|
return SemIR::InstId::None;
|
|
}
|
|
// Clang would produce a warning for classes with uninitialized
|
|
// [[clang::requires_init]] fields for which default initialization is
|
|
// performed, and we don't have a good place to produce that warning.
|
|
// That happens if class_decl->hasUninitializedExplicitInitFields() is true.
|
|
//
|
|
// TODO: Consider treating such types as not implementing `Default`.
|
|
auto decl_info =
|
|
DeclInfo{.decl = clang_sema.LookupDefaultConstructor(class_decl),
|
|
.signature = {.num_params = 0}};
|
|
auto fn_id = GetFunctionId(context, loc_id, decl_info);
|
|
if (fn_id == SemIR::ErrorInst::InstId || fn_id == SemIR::InstId::None) {
|
|
return fn_id;
|
|
}
|
|
return BuildCustomWitness(context, loc_id, query_self_const_id,
|
|
query_specific_interface_id, {fn_id});
|
|
}
|
|
|
|
static auto BuildDestroyWitness(
|
|
Context& context, SemIR::LocId loc_id,
|
|
SemIR::ConstantId query_self_const_id,
|
|
SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId {
|
|
auto& clang_sema = context.clang_sema();
|
|
|
|
// TODO: This should provide `Destroy` for enums and other trivially
|
|
// destructible types.
|
|
auto* class_decl = TypeAsClassDecl(context, query_self_const_id);
|
|
if (!class_decl) {
|
|
return SemIR::InstId::None;
|
|
}
|
|
auto decl_info = DeclInfo{.decl = clang_sema.LookupDestructor(class_decl),
|
|
.signature = {.num_params = 0}};
|
|
auto fn_id = GetFunctionId(context, loc_id, decl_info);
|
|
if (fn_id == SemIR::ErrorInst::InstId || fn_id == SemIR::InstId::None) {
|
|
return fn_id;
|
|
}
|
|
return BuildCustomWitness(context, loc_id, query_self_const_id,
|
|
query_specific_interface_id, {fn_id});
|
|
}
|
|
|
|
auto LookupCppImpl(Context& context, SemIR::LocId loc_id,
|
|
CoreInterface core_interface,
|
|
SemIR::ConstantId query_self_const_id,
|
|
SemIR::SpecificInterfaceId query_specific_interface_id,
|
|
const TypeStructure* best_impl_type_structure,
|
|
SemIR::LocId best_impl_loc_id) -> SemIR::InstId {
|
|
// TODO: Infer a C++ type structure and check whether it's less strict than
|
|
// the best Carbon type structure.
|
|
static_cast<void>(best_impl_type_structure);
|
|
static_cast<void>(best_impl_loc_id);
|
|
|
|
switch (core_interface) {
|
|
case CoreInterface::Copy:
|
|
return BuildCopyWitness(context, loc_id, query_self_const_id,
|
|
query_specific_interface_id);
|
|
case CoreInterface::CppUnsafeDeref:
|
|
return BuildCppUnsafeDerefWitness(context, loc_id, query_self_const_id,
|
|
query_specific_interface_id);
|
|
case CoreInterface::Default:
|
|
return BuildDefaultWitness(context, loc_id, query_self_const_id,
|
|
query_specific_interface_id);
|
|
case CoreInterface::Destroy:
|
|
return BuildDestroyWitness(context, loc_id, query_self_const_id,
|
|
query_specific_interface_id);
|
|
|
|
// IntFitsIn is for Carbon integer types only.
|
|
case CoreInterface::IntFitsIn:
|
|
return SemIR::InstId::None;
|
|
|
|
case CoreInterface::Unknown:
|
|
CARBON_FATAL("unexpected CoreInterface `{0}`", core_interface);
|
|
}
|
|
}
|
|
|
|
} // namespace Carbon::Check
|