Author: Timm Baeder Date: 2025-04-24T22:05:45+02:00 New Revision: 425b9539684be00f3c8ccde54dbab18ce9bc8ebd
URL: https://github.com/llvm/llvm-project/commit/425b9539684be00f3c8ccde54dbab18ce9bc8ebd DIFF: https://github.com/llvm/llvm-project/commit/425b9539684be00f3c8ccde54dbab18ce9bc8ebd.diff LOG: [clang][bytecode] Emit diagnostics from GetGlobalUnchecked (#137203) If the global is uninitialized. Added: Modified: clang/lib/AST/ByteCode/Interp.h clang/test/AST/ByteCode/cxx11.cpp clang/test/SemaCXX/constant-expression-p2280r4.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 0a52a64240c04..0cfeed86f0b51 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -1446,7 +1446,7 @@ bool GetGlobal(InterpState &S, CodePtr OpPC, uint32_t I) { template <PrimType Name, class T = typename PrimConv<Name>::T> bool GetGlobalUnchecked(InterpState &S, CodePtr OpPC, uint32_t I) { const Pointer &Ptr = S.P.getPtrGlobal(I); - if (!Ptr.isInitialized()) + if (!CheckInitialized(S, OpPC, Ptr, AK_Read)) return false; S.Stk.push<T>(Ptr.deref<T>()); return true; diff --git a/clang/test/AST/ByteCode/cxx11.cpp b/clang/test/AST/ByteCode/cxx11.cpp index 004f704145afd..5daf6adf08cf5 100644 --- a/clang/test/AST/ByteCode/cxx11.cpp +++ b/clang/test/AST/ByteCode/cxx11.cpp @@ -194,3 +194,11 @@ namespace DynamicCast { int g : (S*)(void*)(sptr) == sptr; }; } + +namespace GlobalInitializer { + extern int &g; // both-note {{here}} + struct S { + int G : g; // both-error {{constant expression}} \ + // both-note {{initializer of 'g' is unknown}} + }; +} diff --git a/clang/test/SemaCXX/constant-expression-p2280r4.cpp b/clang/test/SemaCXX/constant-expression-p2280r4.cpp index f22430a0e88a2..0cdc16ed4e822 100644 --- a/clang/test/SemaCXX/constant-expression-p2280r4.cpp +++ b/clang/test/SemaCXX/constant-expression-p2280r4.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -std=c++23 -verify=expected,nointerpreter %s -// RUN: %clang_cc1 -std=c++23 -verify %s -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -std=c++23 -verify %s +// RUN: %clang_cc1 -std=c++23 -verify=expected,interpreter %s -fexperimental-new-constant-interpreter using size_t = decltype(sizeof(0)); @@ -48,10 +48,11 @@ void splash(Swim& swam) { } extern Swim dc; -extern Swim& trident; +extern Swim& trident; // interpreter-note {{declared here}} constexpr auto& sandeno = typeid(dc); // ok: can only be typeid(Swim) -constexpr auto& gallagher = typeid(trident); // expected-error {{constexpr variable 'gallagher' must be initialized by a constant expression}} +constexpr auto& gallagher = typeid(trident); // expected-error {{constexpr variable 'gallagher' must be initialized by a constant expression}} \ + // interpreter-note {{initializer of 'trident' is unknown}} namespace explicitThis { struct C { @@ -157,18 +158,18 @@ int g() { namespace GH128409 { int &ff(); - int &x = ff(); // nointerpreter-note {{declared here}} + int &x = ff(); // expected-note {{declared here}} constinit int &z = x; // expected-error {{variable does not have a constant initializer}} \ // expected-note {{required by 'constinit' specifier here}} \ - // nointerpreter-note {{initializer of 'x' is not a constant expression}} + // expected-note {{initializer of 'x' is not a constant expression}} } namespace GH129845 { int &ff(); - int &x = ff(); // nointerpreter-note {{declared here}} + int &x = ff(); // expected-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 {{initializer of 'x' is not a constant expression}} + // expected-note {{initializer of 'x' is not a constant expression}} const A* gg = &g; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits