[clang] 364757d - [clang][Interp] Fix compiling undefined templated functions (#67232)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 25 08:28:49 PDT 2023
Author: Timm Baeder
Date: 2023-09-25T17:28:44+02:00
New Revision: 364757d2d5e1498239566941f8ba334e9846c53b
URL: https://github.com/llvm/llvm-project/commit/364757d2d5e1498239566941f8ba334e9846c53b
DIFF: https://github.com/llvm/llvm-project/commit/364757d2d5e1498239566941f8ba334e9846c53b.diff
LOG: [clang][Interp] Fix compiling undefined templated functions (#67232)
Added:
Modified:
clang/lib/AST/Interp/ByteCodeEmitter.cpp
clang/lib/AST/Interp/Context.cpp
clang/lib/AST/Interp/Function.h
clang/test/AST/Interp/functions.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
index 14593fbffa0e99d..23c28b430d81c22 100644
--- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp
+++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
@@ -92,8 +92,12 @@ ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
assert(Func);
// For not-yet-defined functions, we only create a Function instance and
// compile their body later.
- if (!FuncDecl->isDefined())
+ if (!FuncDecl->isDefined()) {
+ Func->setDefined(false);
return Func;
+ }
+
+ Func->setDefined(true);
// Lambda static invokers are a special case that we emit custom code for.
bool IsEligibleForCompilation = false;
diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp
index 1c1aacbc8bb9e7d..e84c0f6aae7ee93 100644
--- a/clang/lib/AST/Interp/Context.cpp
+++ b/clang/lib/AST/Interp/Context.cpp
@@ -215,8 +215,8 @@ Context::getOverridingFunction(const CXXRecordDecl *DynamicDecl,
const Function *Context::getOrCreateFunction(const FunctionDecl *FD) {
assert(FD);
const Function *Func = P->getFunction(FD);
- bool IsBeingCompiled = Func && !Func->isFullyCompiled();
- bool WasNotDefined = Func && !Func->isConstexpr() && !Func->hasBody();
+ bool IsBeingCompiled = Func && Func->isDefined() && !Func->isFullyCompiled();
+ bool WasNotDefined = Func && !Func->isConstexpr() && !Func->isDefined();
if (IsBeingCompiled)
return Func;
diff --git a/clang/lib/AST/Interp/Function.h b/clang/lib/AST/Interp/Function.h
index 5444c9f59cda7ea..0bae314e97701d9 100644
--- a/clang/lib/AST/Interp/Function.h
+++ b/clang/lib/AST/Interp/Function.h
@@ -169,6 +169,9 @@ class Function final {
/// Checks if the function already has a body attached.
bool hasBody() const { return HasBody; }
+ /// Checks if the function is defined.
+ bool isDefined() const { return Defined; }
+
unsigned getBuiltinID() const { return F->getBuiltinID(); }
bool isBuiltin() const { return F->getBuiltinID() != 0; }
@@ -204,6 +207,7 @@ class Function final {
}
void setIsFullyCompiled(bool FC) { IsFullyCompiled = FC; }
+ void setDefined(bool D) { Defined = D; }
private:
friend class Program;
@@ -245,6 +249,7 @@ class Function final {
bool HasRVO = false;
/// If we've already compiled the function's body.
bool HasBody = false;
+ bool Defined = false;
public:
/// Dumps the disassembled bytecode to \c llvm::errs().
diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp
index 331df74d50b3d62..5cdecbff1e9d3d4 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -332,3 +332,14 @@ namespace InvalidReclRefs {
}
#endif
}
+
+namespace TemplateUndefined {
+ template<typename T> constexpr int consume(T);
+ // ok, not a constant expression.
+ const int k = consume(0);
+
+ template<typename T> constexpr int consume(T) { return 0; }
+ // ok, constant expression.
+ constexpr int l = consume(0);
+ static_assert(l == 0, "");
+}
More information about the cfe-commits
mailing list