llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Eli Friedman (efriedma-quic) <details> <summary>Changes</summary> Perform the check for constexpr-unknown values in the same place we perform checks for other values which don't count as constant expressions. While I'm here, also fix a rejects-valid with a reference that doesn't have an initializer. This diagnostic was also covering up some of the bugs here. The existing behavior with -fexperimental-new-constant-interpreter seems to be correct, but the diagnostics are slightly different; it would be helpful if someone could check on that as a followup. Followup to #<!-- -->128409. Fixes #<!-- -->129844. Fixes #<!-- -->129845. --- Full diff: https://github.com/llvm/llvm-project/pull/129952.diff 4 Files Affected: - (modified) clang/lib/AST/ExprConstant.cpp (+14-13) - (modified) clang/test/CodeGenCXX/cxx23-p2280r4.cpp (+12) - (modified) clang/test/SemaCXX/constant-expression-cxx11.cpp (+2-2) - (modified) clang/test/SemaCXX/constant-expression-p2280r4.cpp (+24-1) ``````````diff diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index d9a1e5bb42343..6b4afc099ad16 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2419,6 +2419,18 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, LVal.getLValueCallIndex() == 0) && "have call index for global lvalue"); + if (LVal.allowConstexprUnknown()) { + if (BaseVD) { + Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) + << BaseVD; + NoteLValueLocation(Info, Base); + } else { + Info.FFDiag(Loc); + } + return false; + } + + if (Base.is<DynamicAllocLValue>()) { Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc) << IsReferenceType << !Designator.Entries.empty(); @@ -3597,7 +3609,8 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, // expressions here; doing so would regress diagnostics for things like // reading from a volatile constexpr variable. if ((Info.getLangOpts().CPlusPlus && !VD->hasConstantInitialization() && - VD->mightBeUsableInConstantExpressions(Info.Ctx)) || + VD->mightBeUsableInConstantExpressions(Info.Ctx) && + !AllowConstexprUnknown) || ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) && !Info.getLangOpts().CPlusPlus11 && !VD->hasICEInitializer(Info.Ctx))) { if (Init) { @@ -16993,18 +17006,6 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx, if (!Info.discardCleanups()) llvm_unreachable("Unhandled cleanup; missing full expression marker?"); - - if (Value.allowConstexprUnknown()) { - assert(Value.isLValue() && "Expected an lvalue"); - auto Base = Value.getLValueBase(); - const auto *NewVD = Base.dyn_cast<const ValueDecl *>(); - if (!NewVD) - NewVD = VD; - Info.FFDiag(getExprLoc(), diag::note_constexpr_var_init_non_constant, 1) - << NewVD; - NoteLValueLocation(Info, Base); - return false; - } } return CheckConstantExpression(Info, DeclLoc, DeclTy, Value, diff --git a/clang/test/CodeGenCXX/cxx23-p2280r4.cpp b/clang/test/CodeGenCXX/cxx23-p2280r4.cpp index d5409be451df0..c91457e5c20de 100644 --- a/clang/test/CodeGenCXX/cxx23-p2280r4.cpp +++ b/clang/test/CodeGenCXX/cxx23-p2280r4.cpp @@ -13,3 +13,15 @@ int& test() { auto &i = s; return i; } + +// CHECK: @_Z1fv( +// CHECK-NEXT: entry: +// CHECK-NEXT: getelementptr inbounds nuw %struct.B +// CHECK-NEXT: getelementptr inbounds nuw %struct.A +// CHECK-NEXT: [[X:%.*]] = load ptr, ptr @x, align 8 +// CHECK-NEXT: store ptr [[X]] +int &ff(); +int &x = ff(); +struct A { int& x; }; +struct B { A x[20]; }; +B f() { return {x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x}; } diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index 76e2f81947051..c35f3a5632a05 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -1472,8 +1472,8 @@ namespace ConvertedConstantExpr { enum class E { em = m, en = n, // expected-error {{enumerator value is not a constant expression}} cxx11_20-note {{initializer of 'n' is unknown}} - eo = (m + // pre-cxx23-error {{not a constant expression}} - n // cxx11_20-note {{initializer of 'n' is unknown}} cxx23-error {{not a constant expression}} + eo = (m + // expected-error {{not a constant expression}} + n // cxx11_20-note {{initializer of 'n' is unknown}} ), eq = reinterpret_cast<long>((int*)0) // expected-error {{not a constant expression}} expected-note {{reinterpret_cast}} }; diff --git a/clang/test/SemaCXX/constant-expression-p2280r4.cpp b/clang/test/SemaCXX/constant-expression-p2280r4.cpp index 65e5e6b34b48f..731b0e9b03046 100644 --- a/clang/test/SemaCXX/constant-expression-p2280r4.cpp +++ b/clang/test/SemaCXX/constant-expression-p2280r4.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++23 -verify %s +// RUN: %clang_cc1 -std=c++23 -verify=expected,nointerpreter %s // RUN: %clang_cc1 -std=c++23 -verify %s -fexperimental-new-constant-interpreter using size_t = decltype(sizeof(0)); @@ -154,3 +154,26 @@ int g() { static_assert(f(arr) == 5); } } + +namespace GH128409 { + int &ff(); + int &x = ff(); // nointerpreter-note {{declared here}} + constinit int &z = x; // expected-error {{variable does not have a constant initializer}} + // expected-note@-1 {{required by 'constinit' specifier here}} + // nointerpreter-note@-2 {{initializer of 'x' is not a constant expression}} +} + +namespace GH129845 { + int &ff(); + int &x = ff(); // nointerpreter-note {{declared here}} + struct A { int& x; }; + constexpr A g = {x}; // expected-error {{constexpr variable 'g' must be initialized by a constant expression}} + // nointerpreter-note@-1 {{initializer of 'x' is not a constant expression}} + const A* gg = &g; +} + +namespace extern_reference_used_as_unknown { + extern int &x; + int y; + constinit int& g = (x,y); // expected-warning {{left operand of comma operator has no effect}} +} `````````` </details> https://github.com/llvm/llvm-project/pull/129952 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits