Author: Timm Bäder Date: 2024-02-15T20:17:51+01:00 New Revision: 6a8ab129300bfdf7cc58e023b06e0aada4458205
URL: https://github.com/llvm/llvm-project/commit/6a8ab129300bfdf7cc58e023b06e0aada4458205 DIFF: https://github.com/llvm/llvm-project/commit/6a8ab129300bfdf7cc58e023b06e0aada4458205.diff LOG: [clang][Interp] Properly emit call ops to invalid functions Just like everywhere else, we can't just abort compilation because a function is invalid. We need to emit the Call op and let later interpretation handle the failure. This fixes a long standing FIXME comment. Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/Interp.cpp clang/test/AST/Interp/cxx20.cpp clang/test/AST/Interp/records.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index db6d818eef334b..e4b48c4e946f13 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -2835,14 +2835,6 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) { const Function *Func = getFunction(FuncDecl); if (!Func) return false; - // If the function is being compiled right now, this is a recursive call. - // In that case, the function can't be valid yet, even though it will be - // later. - // If the function is already fully compiled but not constexpr, it was - // found to be faulty earlier on, so bail out. - if (Func->isFullyCompiled() && !Func->isConstexpr()) - return false; - assert(HasRVO == Func->hasRVO()); bool HasQualifier = false; diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index 2338f88569db8b..2a51f18adf02c5 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -477,6 +477,11 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { if (!DiagDecl->isDefined() && S.checkingPotentialConstantExpression()) return false; + // If the declaration is defined _and_ declared 'constexpr', the below + // diagnostic doesn't add anything useful. + if (DiagDecl->isDefined() && DiagDecl->isConstexpr()) + return false; + S.FFDiag(Loc, diag::note_constexpr_invalid_function, 1) << DiagDecl->isConstexpr() << (bool)CD << DiagDecl; S.Note(DiagDecl->getLocation(), diag::note_declared_at); diff --git a/clang/test/AST/Interp/cxx20.cpp b/clang/test/AST/Interp/cxx20.cpp index 0af553a77892e6..0fc5d977b59f4c 100644 --- a/clang/test/AST/Interp/cxx20.cpp +++ b/clang/test/AST/Interp/cxx20.cpp @@ -230,15 +230,13 @@ namespace ConstThis { // ref-note {{declared const here}} int a; public: - constexpr Foo() { // expected-note {{declared here}} + constexpr Foo() { this->a = 10; T = 13; // expected-error {{cannot assign to non-static data member 'T' with const-qualified type}} \ // ref-error {{cannot assign to non-static data member 'T' with const-qualified type}} } }; constexpr Foo F; // expected-error {{must be initialized by a constant expression}} \ - // FIXME: The following note is wrong. \ - // expected-note {{undefined constructor 'Foo' cannot be used in a constant expression}} \ // ref-error {{must be initialized by a constant expression}} diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 93da831f3bda0a..62f1f1d6e426c3 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -1232,10 +1232,9 @@ namespace InheritedConstructor { namespace InvalidCtorInitializer { struct X { int Y; - constexpr X() // expected-note {{declared here}} + constexpr X() : Y(fo_o_()) {} // both-error {{use of undeclared identifier 'fo_o_'}} }; // no crash on evaluating the constexpr ctor. - constexpr int Z = X().Y; // both-error {{constexpr variable 'Z' must be initialized by a constant expression}} \ - // expected-note {{undefined constructor 'X'}} + constexpr int Z = X().Y; // both-error {{constexpr variable 'Z' must be initialized by a constant expression}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits