Skip to content

Commit d5473fe

Browse files
committed
[cxx-interop] Do not import template type arguments
Prior to this patch, we eagerly imported template type arguments. A consequence of doing so is that we over-instantiate (potentially unused) type arguments, which causes unnecessary errors. The only apparent use we have for these type arguments are to check whether they are unsafe, so that we can mark the instantiated type as unsafe as well... even if the instantiated type does not use its unsafe template type argument at all. Note that using un-instantiatable types in template type arguments is supported in C++. The test case included in this patch validates this behavior, for both missing member and incomplete type errors. Note, also, that as of this patch, dumping the module interface of CxxModule actually causes swift-ide-test to emit compiler errors, since it tries to instantiate the invalid types MissingMember<Empty> and IncompleteField<Incomplete>. However, these errors are simply swallowed by swift-ide-test, so they should be harmless, though we should probably get rid of them entirely in future work. rdar://145238539
1 parent 23474f9 commit d5473fe

File tree

2 files changed

+53
-28
lines changed

2 files changed

+53
-28
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2298,34 +2298,6 @@ namespace {
22982298
}
22992299
}
23002300

2301-
// We have to do this after populating ImportedDecls to avoid importing
2302-
// the same decl multiple times. Also after we imported the bases.
2303-
if (const auto *ctsd =
2304-
dyn_cast<clang::ClassTemplateSpecializationDecl>(decl)) {
2305-
for (auto arg : ctsd->getTemplateArgs().asArray()) {
2306-
llvm::SmallVector<clang::TemplateArgument, 1> nonPackArgs;
2307-
if (arg.getKind() == clang::TemplateArgument::Pack) {
2308-
auto pack = arg.getPackAsArray();
2309-
nonPackArgs.assign(pack.begin(), pack.end());
2310-
} else {
2311-
nonPackArgs.push_back(arg);
2312-
}
2313-
for (auto realArg : nonPackArgs) {
2314-
if (realArg.getKind() != clang::TemplateArgument::Type)
2315-
continue;
2316-
auto SwiftType = Impl.importTypeIgnoreIUO(
2317-
realArg.getAsType(), ImportTypeKind::Abstract,
2318-
[](Diagnostic &&diag) {}, false, Bridgeability::None,
2319-
ImportTypeAttrs());
2320-
if (SwiftType && SwiftType->isUnsafe()) {
2321-
auto attr = new (Impl.SwiftContext) UnsafeAttr(/*implicit=*/true);
2322-
result->getAttrs().add(attr);
2323-
break;
2324-
}
2325-
}
2326-
}
2327-
}
2328-
23292301
bool isNonEscapable = false;
23302302
if (evaluateOrDefault(
23312303
Impl.SwiftContext.evaluator,
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// RUN: split-file %s %t
2+
// RUN: %target-clang -c -o /dev/null -Xclang -verify -I %t/Inputs %t/cxx.cpp
3+
// RUN: %target-swift-frontend -typecheck -verify -cxx-interoperability-mode=default -I %t%{fs-sep}Inputs -verify-additional-file %t%{fs-sep}Inputs%{fs-sep}CxxHeader.h %t%{fs-sep}main.swift
4+
// RUN: %target-swift-ide-test -print-module -module-to-print=CxxModule -I %t/Inputs -source-filename=x -cxx-interoperability-mode=default | %FileCheck %t/Inputs/CxxHeader.h
5+
6+
//--- Inputs/module.modulemap
7+
module CxxModule {
8+
requires cplusplus
9+
header "CxxHeader.h"
10+
}
11+
12+
//--- Inputs/CxxHeader.h
13+
#pragma once
14+
15+
struct Empty {};
16+
template <typename T> struct MissingMember { typename T::Missing member; };
17+
using SUB = MissingMember<Empty>;
18+
19+
struct Incomplete;
20+
template <typename T> struct IncompleteField { T member; };
21+
using INC = IncompleteField<Incomplete>;
22+
23+
template <typename S = SUB, typename I = INC> struct DefaultedTemplateArgs {};
24+
using DefaultedTemplateArgsInst = DefaultedTemplateArgs<>;
25+
26+
// CHECK: struct DefaultedTemplateArgs<MissingMember<Empty>, IncompleteField<Incomplete>> {
27+
// CHECK: }
28+
// CHECK: typealias DefaultedTemplateArgsInst = DefaultedTemplateArgs<MissingMember<Empty>, IncompleteField<Incomplete>>
29+
30+
template <typename S, typename I> struct ThrowsAwayTemplateArgs {};
31+
using ThrowsAwayTemplateArgsInst = ThrowsAwayTemplateArgs<SUB, INC>;
32+
33+
// CHECK: struct ThrowsAwayTemplateArgs<MissingMember<Empty>, IncompleteField<Incomplete>> {
34+
// CHECK: }
35+
// CHECK: typealias ThrowsAwayTemplateArgsInst = ThrowsAwayTemplateArgs<MissingMember<Empty>, IncompleteField<Incomplete>>
36+
37+
//--- cxx.cpp
38+
// expected-no-diagnostics
39+
#include <CxxHeader.h>
40+
void make(void) {
41+
DefaultedTemplateArgs<> dta{};
42+
DefaultedTemplateArgsInst dtai{};
43+
44+
ThrowsAwayTemplateArgs<SUB, INC> tata{};
45+
ThrowsAwayTemplateArgsInst tatai{};
46+
}
47+
48+
//--- main.swift
49+
import CxxModule
50+
func make() {
51+
let _: DefaultedTemplateArgsInst = .init()
52+
let _: ThrowsAwayTemplateArgsInst = .init()
53+
}

0 commit comments

Comments
 (0)