Skip to content

Commit 364757d

Browse files
authored
[clang][Interp] Fix compiling undefined templated functions (#67232)
1 parent 029c9c3 commit 364757d

File tree

4 files changed

+23
-3
lines changed

4 files changed

+23
-3
lines changed

clang/lib/AST/Interp/ByteCodeEmitter.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,12 @@ ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
9292
assert(Func);
9393
// For not-yet-defined functions, we only create a Function instance and
9494
// compile their body later.
95-
if (!FuncDecl->isDefined())
95+
if (!FuncDecl->isDefined()) {
96+
Func->setDefined(false);
9697
return Func;
98+
}
99+
100+
Func->setDefined(true);
97101

98102
// Lambda static invokers are a special case that we emit custom code for.
99103
bool IsEligibleForCompilation = false;

clang/lib/AST/Interp/Context.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ Context::getOverridingFunction(const CXXRecordDecl *DynamicDecl,
215215
const Function *Context::getOrCreateFunction(const FunctionDecl *FD) {
216216
assert(FD);
217217
const Function *Func = P->getFunction(FD);
218-
bool IsBeingCompiled = Func && !Func->isFullyCompiled();
219-
bool WasNotDefined = Func && !Func->isConstexpr() && !Func->hasBody();
218+
bool IsBeingCompiled = Func && Func->isDefined() && !Func->isFullyCompiled();
219+
bool WasNotDefined = Func && !Func->isConstexpr() && !Func->isDefined();
220220

221221
if (IsBeingCompiled)
222222
return Func;

clang/lib/AST/Interp/Function.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,9 @@ class Function final {
169169
/// Checks if the function already has a body attached.
170170
bool hasBody() const { return HasBody; }
171171

172+
/// Checks if the function is defined.
173+
bool isDefined() const { return Defined; }
174+
172175
unsigned getBuiltinID() const { return F->getBuiltinID(); }
173176

174177
bool isBuiltin() const { return F->getBuiltinID() != 0; }
@@ -204,6 +207,7 @@ class Function final {
204207
}
205208

206209
void setIsFullyCompiled(bool FC) { IsFullyCompiled = FC; }
210+
void setDefined(bool D) { Defined = D; }
207211

208212
private:
209213
friend class Program;
@@ -245,6 +249,7 @@ class Function final {
245249
bool HasRVO = false;
246250
/// If we've already compiled the function's body.
247251
bool HasBody = false;
252+
bool Defined = false;
248253

249254
public:
250255
/// Dumps the disassembled bytecode to \c llvm::errs().

clang/test/AST/Interp/functions.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,3 +332,14 @@ namespace InvalidReclRefs {
332332
}
333333
#endif
334334
}
335+
336+
namespace TemplateUndefined {
337+
template<typename T> constexpr int consume(T);
338+
// ok, not a constant expression.
339+
const int k = consume(0);
340+
341+
template<typename T> constexpr int consume(T) { return 0; }
342+
// ok, constant expression.
343+
constexpr int l = consume(0);
344+
static_assert(l == 0, "");
345+
}

0 commit comments

Comments
 (0)