Skip to content

Commit fa665c4

Browse files
author
iclsrc
committed
Merge from 'sycl' to 'sycl-web' (17 commits)
2 parents 8efd590 + 08a74f9 commit fa665c4

File tree

114 files changed

+5205
-909
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+5205
-909
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,4 @@ llvm/test/Instrumentation/MemorySanitizer/ @intel/dpcpp-sanitizers-review
208208
llvm/test/Instrumentation/ThreadSanitizer/ @intel/dpcpp-sanitizers-review
209209
sycl/test-e2e/AddressSanitizer/ @intel/dpcpp-sanitizers-review
210210
sycl/test-e2e/MemorySanitizer/ @intel/dpcpp-sanitizers-review
211+
sycl/test-e2e/ThreadSanitizer/ @intel/dpcpp-sanitizers-review

.github/workflows/docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
fetch-depth: 1
6666
- name: Get subprojects that have doc changes
6767
id: docs-changed-subprojects
68-
uses: tj-actions/changed-files@v46
68+
uses: step-security/changed-files@3dbe17c78367e7d60f00d78ae6781a35be47b4a1 # v45.0.1
6969
with:
7070
files_yaml: |
7171
llvm:

.github/workflows/pr-code-format.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434

3535
- name: Get changed files
3636
id: changed-files
37-
uses: tj-actions/changed-files@v46
37+
uses: step-security/changed-files@3dbe17c78367e7d60f00d78ae6781a35be47b4a1 # v45.0.1
3838
with:
3939
separator: ","
4040
skip_initial_fetch: true

.github/workflows/sycl-windows-run-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ jobs:
164164
uses: ./devops/actions/run-tests/windows/cts
165165
with:
166166
ref: ${{ inputs.tests_ref || 'main' }}
167+
cts_exclude_ref: ${{ inputs.repo_ref }}
167168
extra_cmake_args: ${{ inputs.extra_cmake_args }}
168169
cts_testing_mode: ${{ inputs.cts_testing_mode }}
169170
sycl_cts_artifact: ${{ inputs.sycl_cts_artifact }}

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-
197197
CODEGENOPT(HIPCorrectlyRoundedDivSqrt, 1, 1) ///< -fno-hip-fp32-correctly-rounded-divide-sqrt
198198
CODEGENOPT(DisableBlockSignatureString, 1, 0) ///< Set when -fdisable-block-signature-string is enabled.
199199
CODEGENOPT(HIPSaveKernelArgName, 1, 0) ///< Set when -fhip-kernel-arg-name is enabled.
200-
CODEGENOPT(SYCLFp32PrecSqrt, 1, 0) ///< -fsycl-fp32-prec-sqrt
201200
CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get unique names.
202201
CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using profile information.
203202
CODEGENOPT(PPCUseFullRegisterNames, 1, 0) ///< Print full register names in assembly

clang/include/clang/Basic/DiagnosticDriverKinds.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ def warn_drv_object_size_disabled_O0 : Warning<
573573
def warn_drv_deprecated_option : Warning<
574574
"option '%0' is deprecated, use '%1' directly instead">, InGroup<Deprecated>;
575575
def warn_drv_deprecated_option_release : Warning<
576-
"option '%0' is deprecated and will be removed in a future release">,
576+
"option '%0' is deprecated and will be removed in a future release%select{|, use '%2' instead}1">,
577577
InGroup<Deprecated>;
578578
def warn_drv_deprecated_argument_option_release : Warning<
579579
"argument '%0' for option '%1' is deprecated and will be removed in a "

clang/include/clang/Driver/Options.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7006,9 +7006,9 @@ def fsycl_device_lib_jit_link : Flag<["-"], "fsycl-device-lib-jit-link">,
70067006
def fno_sycl_device_lib_jit_link : Flag<["-"], "fno-sycl-device-lib-jit-link">,
70077007
HelpText<"Disables sycl device library jit link (experimental)">;
70087008
def fsycl_fp32_prec_sqrt : Flag<["-"], "fsycl-fp32-prec-sqrt">,
7009+
Alias<foffload_fp32_prec_sqrt>, Flags<[Deprecated]>,
70097010
Visibility<[ClangOption, CC1Option]>, HelpText<"SYCL only. Specify that "
7010-
"single precision floating-point sqrt is correctly rounded.">,
7011-
MarshallingInfoFlag<CodeGenOpts<"SYCLFp32PrecSqrt">>;
7011+
"single precision floating-point sqrt is correctly rounded. (deprecated)">;
70127012
def fsycl_default_sub_group_size
70137013
: Separate<["-"], "fsycl-default-sub-group-size">,
70147014
HelpText<"Set the default sub group size for SYCL kernels">,

clang/lib/Driver/Driver.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,16 @@ InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings,
356356
while (Used->getAlias())
357357
Used = Used->getAlias();
358358
if (Used->getOption().hasFlag(options::Deprecated)) {
359-
Diag(diag::warn_drv_deprecated_option_release) << Used->getAsString(Args);
359+
// Some deprecated options have a replacement option. In these cases,
360+
// add the replacement option string to the diagnostic.
361+
SmallString<128> AliasOpt;
362+
if (Used != A) {
363+
AliasOpt = A->getSpelling();
364+
if (A->getNumValues())
365+
AliasOpt += A->getValue();
366+
}
367+
Diag(diag::warn_drv_deprecated_option_release)
368+
<< Used->getAsString(Args) << !AliasOpt.empty() << AliasOpt;
360369
ContainsError |= Diags.getDiagnosticLevel(
361370
diag::warn_drv_deprecated_option_release,
362371
SourceLocation()) > DiagnosticsEngine::Warning;

clang/lib/Driver/SanitizerArgs.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,9 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
12831283

12841284
CmdArgs.push_back("-mllvm");
12851285
CmdArgs.push_back("-msan-eager-checks=1");
1286+
1287+
CmdArgs.push_back("-mllvm");
1288+
CmdArgs.push_back("-msan-poison-stack-with-call=1");
12861289
} else if (Sanitizers.has(SanitizerKind::Thread)) {
12871290
CmdArgs.push_back("-fsanitize=thread");
12881291
// The tsan function entry/exit builtins are used to record stack

clang/lib/Driver/ToolChains/AMDGPU.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,11 +1071,10 @@ ROCMToolChain::getCommonDeviceLibNames(
10711071
bool FastRelaxedMath = DriverArgs.hasFlag(options::OPT_ffast_math,
10721072
options::OPT_fno_fast_math, false);
10731073
bool CorrectSqrt = false;
1074-
if (DeviceOffloadingKind == Action::OFK_SYCL) {
1074+
if (DeviceOffloadingKind == Action::OFK_SYCL)
10751075
// When using SYCL, sqrt is only correctly rounded if the flag is specified
1076-
CorrectSqrt = DriverArgs.hasArg(options::OPT_fsycl_fp32_prec_sqrt) ||
1077-
DriverArgs.hasArg(options::OPT_foffload_fp32_prec_sqrt);
1078-
} else
1076+
CorrectSqrt = DriverArgs.hasArg(options::OPT_foffload_fp32_prec_sqrt);
1077+
else
10791078
CorrectSqrt = DriverArgs.hasFlag(
10801079
options::OPT_fhip_fp32_correctly_rounded_divide_sqrt,
10811080
options::OPT_fno_hip_fp32_correctly_rounded_divide_sqrt, true);

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3181,17 +3181,18 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
31813181
CmdArgs.push_back(A->getValue());
31823182
}
31833183

3184-
auto addSPIRVArgs = [&](StringRef SPIRVArg) {
3184+
auto addSPIRVArgs = [&](const Arg *PrecArg) {
31853185
if (IsFp32PrecDivSqrtAllowed) {
3186+
OptSpecifier Opt(PrecArg->getOption().getID());
31863187
if (!FPAccuracy.empty())
3187-
EmitAccuracyDiag(D, JA, FPAccuracy, SPIRVArg);
3188-
if (SPIRVArg == "-fno-offload-fp32-prec-div")
3188+
EmitAccuracyDiag(D, JA, FPAccuracy, PrecArg->getSpelling());
3189+
if (Opt == options::OPT_fno_offload_fp32_prec_div)
31893190
NoOffloadFP32PrecDiv = true;
3190-
else if (SPIRVArg == "-fno-offload-fp32-prec-sqrt")
3191+
else if (Opt == options::OPT_fno_offload_fp32_prec_sqrt)
31913192
NoOffloadFP32PrecSqrt = true;
3192-
else if (SPIRVArg == "-foffload-fp32-prec-sqrt")
3193+
else if (Opt == options::OPT_foffload_fp32_prec_sqrt)
31933194
NoOffloadFP32PrecSqrt = false;
3194-
else if (SPIRVArg == "-foffload-fp32-prec-div")
3195+
else if (Opt == options::OPT_foffload_fp32_prec_div)
31953196
NoOffloadFP32PrecDiv = false;
31963197
}
31973198
};
@@ -3218,17 +3219,15 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
32183219
default: continue;
32193220

32203221
case options::OPT_foffload_fp32_prec_div:
3221-
addSPIRVArgs("-foffload-fp32-prec-div");
3222-
break;
32233222
case options::OPT_foffload_fp32_prec_sqrt:
3224-
addSPIRVArgs("-foffload-fp32-prec-sqrt");
3225-
break;
32263223
case options::OPT_fno_offload_fp32_prec_div:
3227-
addSPIRVArgs("-fno-offload-fp32-prec-div");
3228-
break;
32293224
case options::OPT_fno_offload_fp32_prec_sqrt:
3230-
addSPIRVArgs("-fno-offload-fp32-prec-sqrt");
3231-
break;
3225+
if (IsFp32PrecDivSqrtAllowed) {
3226+
addSPIRVArgs(A);
3227+
break;
3228+
}
3229+
// Skip claim, as we didn't use the option.
3230+
continue;
32323231
case options::OPT_fcx_limited_range:
32333232
if (GccRangeComplexOption.empty()) {
32343233
if (Range != LangOptions::ComplexRangeKind::CX_Basic)

clang/lib/Driver/ToolChains/Cuda.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -955,8 +955,7 @@ void CudaToolChain::addClangTargetOptions(
955955
if (DeviceOffloadingKind == Action::OFK_SYCL) {
956956
SYCLInstallation.addSYCLIncludeArgs(DriverArgs, CC1Args);
957957

958-
if (DriverArgs.hasArg(options::OPT_fsycl_fp32_prec_sqrt) ||
959-
DriverArgs.hasArg(options::OPT_foffload_fp32_prec_sqrt))
958+
if (DriverArgs.hasArg(options::OPT_foffload_fp32_prec_sqrt))
960959
CC1Args.push_back("-fcuda-prec-sqrt");
961960

962961
bool FastRelaxedMath = DriverArgs.hasFlag(

clang/lib/Sema/SPIRVBuiltins.td

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -897,15 +897,15 @@ foreach name = ["BitCount"] in {
897897
// 3.32.20. Barrier Instructions
898898

899899
foreach name = ["ControlBarrier"] in {
900-
// TODO: Allow enum flags instead of UInt ?
901-
// TODO: We should enforce that the UInt must be a literal.
902-
def : SPVBuiltin<name, [Void, UInt, UInt, UInt], Attr.Convergent>;
900+
// TODO: Allow enum flags instead of Int ?
901+
// TODO: We should enforce that the Int must be a literal.
902+
def : SPVBuiltin<name, [Void, Int, Int, Int], Attr.Convergent>;
903903
}
904904

905905
foreach name = ["MemoryBarrier"] in {
906-
// TODO: Allow enum flags instead of UInt ?
907-
// TODO: We should enforce that the UInt must be a literal.
908-
def : SPVBuiltin<name, [Void, UInt, UInt]>;
906+
// TODO: Allow enum flags instead of Int ?
907+
// TODO: We should enforce that the Int must be a literal.
908+
def : SPVBuiltin<name, [Void, Int, Int]>;
909909
}
910910

911911
// 3.32.21. Group and Subgroup Instructions

clang/lib/Sema/SemaExpr.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7138,6 +7138,18 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
71387138
return ExprError();
71397139
}
71407140

7141+
// Diagnose function pointers in SYCL.
7142+
if (!FDecl && !getLangOpts().SYCLAllowFuncPtr && getLangOpts().SYCLIsDevice &&
7143+
!isUnevaluatedContext()) {
7144+
bool MaybeConstantExpr = false;
7145+
Expr *NonDirectCallee = TheCall->getCallee();
7146+
if (!NonDirectCallee->isValueDependent())
7147+
MaybeConstantExpr = NonDirectCallee->isCXX11ConstantExpr(getASTContext());
7148+
if (!MaybeConstantExpr)
7149+
SYCL().DiagIfDeviceCode(TheCall->getExprLoc(), diag::err_sycl_restrict)
7150+
<< SemaSYCL::KernelCallFunctionPointer;
7151+
}
7152+
71417153
return CheckForImmediateInvocation(MaybeBindToTemporary(TheCall), FDecl);
71427154
}
71437155

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -687,17 +687,6 @@ class DiagDeviceFunction : public RecursiveASTVisitor<DiagDeviceFunction> {
687687
SemaSYCLRef.Diag(e->getExprLoc(), diag::err_builtin_target_unsupported)
688688
<< Name << "SYCL device";
689689
}
690-
} else if (!SemaSYCLRef.getLangOpts().SYCLAllowFuncPtr &&
691-
!e->isTypeDependent() &&
692-
!isa<CXXPseudoDestructorExpr>(e->getCallee())) {
693-
bool MaybeConstantExpr = false;
694-
Expr *NonDirectCallee = e->getCallee();
695-
if (!NonDirectCallee->isValueDependent())
696-
MaybeConstantExpr =
697-
NonDirectCallee->isCXX11ConstantExpr(SemaSYCLRef.getASTContext());
698-
if (!MaybeConstantExpr)
699-
SemaSYCLRef.Diag(e->getExprLoc(), diag::err_sycl_restrict)
700-
<< SemaSYCL::KernelCallFunctionPointer;
701690
}
702691
return true;
703692
}

clang/test/CodeGenSPIRV/spirv-builtin-lookup.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,19 @@ double acos(double val) {
1515
}
1616

1717
// CHECK: declare noundef double @_Z16__spirv_ocl_acosd(double noundef)
18+
19+
void control_barrier() {
20+
// CHECK-LABEL: @_Z15control_barrierv
21+
// CHECK: call void @_Z22__spirv_ControlBarrieriii
22+
__spirv_ControlBarrier(2, 2, 912);
23+
}
24+
25+
// CHECK: declare void @_Z22__spirv_ControlBarrieriii(i32 noundef, i32 noundef, i32 noundef)
26+
27+
void memory_barrier() {
28+
// CHECK-LABEL: @_Z14memory_barrierv
29+
// CHECK: call void @_Z21__spirv_MemoryBarrierii(
30+
__spirv_MemoryBarrier(0, 2);
31+
}
32+
33+
// CHECK: declare void @_Z21__spirv_MemoryBarrierii(i32 noundef, i32 noundef)

clang/test/CodeGenSYCL/Inputs/sycl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ extern "C" int printf(const char* fmt, ...);
1919

2020
#ifdef __SYCL_DEVICE_ONLY__
2121
__attribute__((convergent)) extern __attribute__((sycl_device)) void
22-
__spirv_ControlBarrier(int, int, int) noexcept;
22+
__spirv_ControlBarrier(int, int, int);
2323
#endif
2424

2525
// Dummy runtime classes to model SYCL API.

clang/test/Driver/sycl-deprecated.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
/// Test for any deprecated options
22
// RUN: %clangxx -fsycl-explicit-simd %s -### 2>&1 | FileCheck %s -DOPTION=-fsycl-explicit-simd
33
// RUN: %clangxx -fno-sycl-explicit-simd %s -### 2>&1 | FileCheck %s -DOPTION=-fno-sycl-explicit-simd
4-
// RUN: %clangxx -fsycl -fsycl-use-bitcode %s -### 2>&1 | FileCheck %s -DOPTION=-fsycl-use-bitcode
5-
// RUN: %clangxx -fsycl -fno-sycl-use-bitcode %s -### 2>&1 | FileCheck %s -DOPTION=-fno-sycl-use-bitcode
64
// RUN: %clangxx -fsycl -fsycl-allow-device-dependencies %s -### 2>&1 | FileCheck %s -DOPTION=-fsycl-allow-device-dependencies
75
// RUN: %clangxx -fsycl -fno-sycl-allow-device-dependencies %s -### 2>&1 | FileCheck %s -DOPTION=-fno-sycl-allow-device-dependencies
86
// CHECK: option '[[OPTION]]' is deprecated and will be removed in a future release
7+
8+
// RUN: %clangxx -fsycl -fsycl-use-bitcode %s -### 2>&1 \
9+
// RUN: | FileCheck %s --check-prefix=CHECK_REPLACE -DOPTION=-fsycl-use-bitcode -DOPTION_REPLACE=-fsycl-device-obj=llvmir
10+
// RUN: %clangxx -fsycl -fno-sycl-use-bitcode %s -### 2>&1 \
11+
// RUN: | FileCheck %s --check-prefix=CHECK_REPLACE -DOPTION=-fno-sycl-use-bitcode -DOPTION_REPLACE=-fsycl-device-obj=spirv
12+
// RUN: %clangxx -fsycl -fsycl-fp32-prec-sqrt %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_REPLACE -DOPTION=-fsycl-fp32-prec-sqrt -DOPTION_REPLACE=-foffload-fp32-prec-sqrt
13+
// CHECK_REPLACE: option '[[OPTION]]' is deprecated and will be removed in a future release, use '[[OPTION_REPLACE]]' instead

clang/test/Driver/sycl-no-prec-sqrt.cpp

Lines changed: 0 additions & 12 deletions
This file was deleted.

clang/test/Driver/sycl-specific-args-diagnostics.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,17 @@
8181
// RUN: %clang_cl -### -fsycl-force-inline-kernel-lambda %s 2>&1 \
8282
// RUN: | FileCheck -check-prefix=WARNING-UNUSED-ARG -DOPT=-fsycl-force-inline-kernel-lambda %s
8383

84-
// Warning should be emitted when using -fsycl-fp32-prec-sqrt without -fsycl
85-
// RUN: %clang -### -fsycl-fp32-prec-sqrt %s 2>&1 \
86-
// RUN: | FileCheck -check-prefix=WARNING-UNUSED-ARG -DOPT=-fsycl-fp32-prec-sqrt %s
87-
// RUN: %clang_cl -### -fsycl-fp32-prec-sqrt %s 2>&1 \
88-
// RUN: | FileCheck -check-prefix=WARNING-UNUSED-ARG -DOPT=-fsycl-fp32-prec-sqrt %s
84+
// Warning should be emitted when using -foffload-fp32-prec-sqrt without -fsycl
85+
// RUN: %clang -### -foffload-fp32-prec-sqrt %s 2>&1 \
86+
// RUN: | FileCheck -check-prefix=WARNING-UNUSED-ARG -DOPT=-foffload-fp32-prec-sqrt %s
87+
// RUN: %clang_cl -### -foffload-fp32-prec-sqrt %s 2>&1 \
88+
// RUN: | FileCheck -check-prefix=WARNING-UNUSED-ARG -DOPT=-foffload-fp32-prec-sqrt %s
89+
90+
// Warning should be emitted when using -foffload-fp32-prec-div without -fsycl
91+
// RUN: %clang -### -foffload-fp32-prec-div %s 2>&1 \
92+
// RUN: | FileCheck -check-prefix=WARNING-UNUSED-ARG -DOPT=-foffload-fp32-prec-div %s
93+
// RUN: %clang_cl -### -foffload-fp32-prec-div %s 2>&1 \
94+
// RUN: | FileCheck -check-prefix=WARNING-UNUSED-ARG -DOPT=-foffload-fp32-prec-div %s
8995

9096
// Warning should be emitted when using -fsycl-id-queries-fit-in-int without -fsycl
9197
// RUN: %clang -### -fsycl-id-queries-fit-in-int %s 2>&1 \

clang/test/SemaSYCL/constexpr-function-pointer.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
// RUN: %clang_cc1 -fsycl-is-device -fsyntax-only -verify -sycl-std=2020 -std=c++17 %s
2+
// RUN: %clang_cc1 -fsycl-is-host -fsyntax-only -verify=host -sycl-std=2020 -std=c++17 %s
23

34
// This test checks that the compiler doesn't emit an error when indirect call
45
// was made through a function pointer that is constant expression, and makes
56
// sure that the error is emitted when a function pointer is not a constant
67
// expression.
78

9+
// host-no-diagnostics
10+
811
void t() {}
912

1013
constexpr auto F = t;
@@ -22,6 +25,8 @@ void bar1(const SomeFunc fptr) {
2225

2326
template <auto f> void fooNTTP() { f(); }
2427

28+
template <typename FTy> void templated(FTy f) { f(); } // #call-templated
29+
2530
__attribute__((sycl_device)) void bar() {
2631
// OK
2732
constexpr auto f = t;
@@ -48,4 +53,19 @@ __attribute__((sycl_device)) void bar() {
4853
fff();
4954

5055
fooNTTP<t>();
56+
57+
templated(t);
58+
// expected-error@#call-templated {{SYCL kernel cannot call through a function pointer}}
59+
// expected-note@-2 {{called by 'bar'}}
60+
}
61+
62+
void from_host() {
63+
const auto f1 = t;
64+
f1();
65+
auto f2 = t;
66+
f2();
67+
68+
fooNTTP<t>();
69+
70+
templated(t);
5171
}

0 commit comments

Comments
 (0)