Author: Timm Baeder Date: 2026-01-09T08:11:17+01:00 New Revision: eec258dcf38d527cf23cb4c30af63446b1074c8d
URL: https://github.com/llvm/llvm-project/commit/eec258dcf38d527cf23cb4c30af63446b1074c8d DIFF: https://github.com/llvm/llvm-project/commit/eec258dcf38d527cf23cb4c30af63446b1074c8d.diff LOG: [clang][bytecode] Diagnose unknown reference params pre-C++23 (#175013) Otherwise, we will ultimately create dummy pointers for them and possibly not diagnose anything. Added: Modified: clang/lib/AST/ByteCode/Compiler.cpp clang/lib/AST/ByteCode/Interp.cpp clang/test/AST/ByteCode/cxx23.cpp clang/test/SemaCXX/constant-expression-p2280r4.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index e85ccafc0e53b..cbee7691565a9 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -7076,6 +7076,10 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) { return this->emitGetPtrParam(It->second.Offset, E); } + + if (!Ctx.getLangOpts().CPlusPlus23 && IsReference) + return this->emitInvalidDeclRef(cast<DeclRefExpr>(E), + /*InitializerFailed=*/false, E); } // Local variables. if (auto It = Locals.find(D); It != Locals.end()) { diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 6444025d6fcf8..0a083a4990856 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -144,14 +144,19 @@ static bool diagnoseUnknownDecl(InterpState &S, CodePtr OpPC, if (isa<ParmVarDecl>(D)) { if (D->getType()->isReferenceType()) { if (S.inConstantContext() && S.getLangOpts().CPlusPlus && - !S.getLangOpts().CPlusPlus11) + !S.getLangOpts().CPlusPlus11) { diagnoseNonConstVariable(S, OpPC, D); - return false; + return false; + } } const SourceInfo &Loc = S.Current->getSource(OpPC); - if (S.getLangOpts().CPlusPlus11) { - S.FFDiag(Loc, diag::note_constexpr_function_param_value_unknown) << D; + if (S.getLangOpts().CPlusPlus23) { + S.FFDiag(Loc, diag::note_constexpr_access_unknown_variable, 1) + << AK_Read << D; + S.Note(D->getLocation(), diag::note_declared_at) << D->getSourceRange(); + } else if (S.getLangOpts().CPlusPlus11) { + S.FFDiag(Loc, diag::note_constexpr_function_param_value_unknown, 1) << D; S.Note(D->getLocation(), diag::note_declared_at) << D->getSourceRange(); } else { S.FFDiag(Loc); diff --git a/clang/test/AST/ByteCode/cxx23.cpp b/clang/test/AST/ByteCode/cxx23.cpp index 4a4ff4b48e8b5..4b87f44d14345 100644 --- a/clang/test/AST/ByteCode/cxx23.cpp +++ b/clang/test/AST/ByteCode/cxx23.cpp @@ -520,3 +520,20 @@ namespace InactiveLocalsInConditionalOp { } #endif + +namespace UnknownParams { + class X { + public: + constexpr operator bool(){ return true; } + }; + int foo(X x) { + static_assert(x); + return 1; + } + + int foo2(X &x) { // all20-note {{declared here}} + static_assert(x); // all20-error {{not an integral constant expression}} \ + // all20-note {{function parameter 'x' with unknown value cannot be used in a constant expression}} + return 1; + } +} diff --git a/clang/test/SemaCXX/constant-expression-p2280r4.cpp b/clang/test/SemaCXX/constant-expression-p2280r4.cpp index 21283c04a1db2..7c8e3e975f091 100644 --- a/clang/test/SemaCXX/constant-expression-p2280r4.cpp +++ b/clang/test/SemaCXX/constant-expression-p2280r4.cpp @@ -35,7 +35,7 @@ constexpr int how_many(Swim& swam) { return (p + 1 - 1)->phelps(); } -void splash(Swim& swam) { // nointerpreter-note {{declared here}} +void splash(Swim& swam) { // expected-note {{declared here}} static_assert(swam.phelps() == 28); // ok static_assert((&swam)->phelps() == 28); // ok Swim* pswam = &swam; // expected-note {{declared here}} @@ -46,7 +46,7 @@ void splash(Swim& swam) { // nointerpreter-note {{declared here} static_assert(swam.lochte() == 12); // expected-error {{static assertion expression is not an integral constant expression}} \ // expected-note {{virtual function called on object 'swam' whose dynamic type is not constant}} static_assert(swam.coughlin == 12); // expected-error {{static assertion expression is not an integral constant expression}} \ - // nointerpreter-note {{read of variable 'swam' whose value is not known}} + // expected-note {{read of variable 'swam' whose value is not known}} } extern Swim dc; @@ -256,14 +256,14 @@ namespace uninit_reference_used { namespace param_reference { constexpr int arbitrary = -12345; - constexpr void f(const int &x = arbitrary) { // nointerpreter-note 3 {{declared here}} interpreter-note {{declared here}} + constexpr void f(const int &x = arbitrary) { // expected-note 3{{declared here}} constexpr const int &v1 = x; // expected-error {{must be initialized by a constant expression}} \ // expected-note {{reference to 'x' is not a constant expression}} constexpr const int &v2 = (x, arbitrary); // expected-warning {{left operand of comma operator has no effect}} constexpr int v3 = x; // expected-error {{must be initialized by a constant expression}} \ - // nointerpreter-note {{read of variable 'x' whose value is not known}} + // expected-note {{read of variable 'x' whose value is not known}} static_assert(x==arbitrary); // expected-error {{static assertion expression is not an integral constant expression}} \ - // nointerpreter-note {{read of variable 'x' whose value is not known}} + // expected-note {{read of variable 'x' whose value is not known}} static_assert(&x - &x == 0); } } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
