Skip to content

Commit df9236c

Browse files
authored
Merge pull request #61552 from apple/egorzhdan/cxx-declval
[cxx-interop] Do not instantiate templates in unevaluated contexts
2 parents 7ae8f39 + 1b41703 commit df9236c

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

lib/IRGen/GenClangDecl.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,15 @@ class ClangDeclFinder
7575
return true;
7676
}
7777

78+
// Do not traverse unevaluated expressions. Doing to might result in compile
79+
// errors if we try to instantiate an un-instantiatable template.
80+
81+
bool VisitCXXNoexceptExpr(clang::CXXNoexceptExpr *NEE) { return false; }
82+
83+
bool VisitCXXTypeidExpr(clang::CXXTypeidExpr *TIE) {
84+
return TIE->isPotentiallyEvaluated();
85+
}
86+
7887
bool shouldVisitTemplateInstantiations() const { return true; }
7988
bool shouldVisitImplicitCode() const { return true; }
8089
};

test/Interop/Cxx/templates/Inputs/module.modulemap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,8 @@ module DependentTypes {
137137
header "dependent-types.h"
138138
requires cplusplus
139139
}
140+
141+
module UnevaluatedContext {
142+
header "unevaluated-context.h"
143+
requires cplusplus
144+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#ifndef TEST_INTEROP_CXX_TEMPLATES_INPUTS_UNEVALUATED_CONTEXT_H
2+
#define TEST_INTEROP_CXX_TEMPLATES_INPUTS_UNEVALUATED_CONTEXT_H
3+
4+
template <typename _Tp>
5+
_Tp __declval(long);
6+
7+
template <typename _Tp>
8+
struct __declval_protector {
9+
static const bool __stop = false;
10+
};
11+
12+
template <typename _Tp>
13+
auto declval() noexcept -> decltype(__declval<_Tp>(0)) {
14+
static_assert(__declval_protector<_Tp>::__stop,
15+
"declval() must not be used!");
16+
return __declval<_Tp>(0);
17+
}
18+
19+
template <class T>
20+
class Vec {
21+
public:
22+
void push_back(const T &__x) {
23+
if (!noexcept(declval<T *>()))
24+
;
25+
}
26+
};
27+
28+
inline void initVector() {
29+
Vec<int> vv;
30+
vv.push_back(0);
31+
}
32+
33+
#endif // TEST_INTEROP_CXX_TEMPLATES_INPUTS_UNEVALUATED_CONTEXT_H
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -enable-experimental-cxx-interop)
2+
//
3+
// REQUIRES: executable_test
4+
5+
import StdlibUnittest
6+
import UnevaluatedContext
7+
8+
var UnevaluatedTestSuite = TestSuite("UnevaluatedContext")
9+
10+
UnevaluatedTestSuite.test("declval") {
11+
initVector()
12+
}
13+
14+
runAllTests()

0 commit comments

Comments
 (0)