Timm =?utf-8?q?Bäder?= <tbae...@redhat.com> Message-ID: In-Reply-To: <llvm.org/llvm/llvm-project/pull/149...@github.com>
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/149330 >From 452950ede23a7a21ca88db3600297d67935ddf51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Thu, 17 Jul 2025 17:04:18 +0200 Subject: [PATCH 1/2] [clang][bytecode] Diagnose dereferencing a null pointer --- clang/lib/AST/ByteCode/Compiler.cpp | 3 +++ clang/lib/AST/ByteCode/Interp.h | 11 +++++++++++ clang/lib/AST/ByteCode/Opcodes.td | 1 + clang/test/AST/ByteCode/complex.cpp | 5 ++--- clang/test/AST/ByteCode/cxx11.cpp | 5 ++--- clang/test/AST/ByteCode/records.cpp | 6 ++---- clang/test/CXX/drs/cwg14xx.cpp | 8 ++++++++ 7 files changed, 29 insertions(+), 10 deletions(-) diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 65ad7caf8913b..952a43a0ecbcf 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -6375,6 +6375,9 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { if (!this->visit(SubExpr)) return false; + if (!this->emitCheckNull(E)) + return false; + if (classifyPrim(SubExpr) == PT_Ptr) return this->emitNarrowPtr(E); return true; diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index aac519d7c74fd..3d2d7be9dc0d9 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -1885,6 +1885,17 @@ inline bool Dump(InterpState &S, CodePtr OpPC) { return true; } +inline bool CheckNull(InterpState &S, CodePtr OpPC) { + const auto &Ptr = S.Stk.peek<Pointer>(); + if (Ptr.isZero()) { + S.FFDiag(S.Current->getSource(OpPC), + diag::note_constexpr_dereferencing_null); + return false; + } + + return true; +} + inline bool VirtBaseHelper(InterpState &S, CodePtr OpPC, const RecordDecl *Decl, const Pointer &Ptr) { Pointer Base = Ptr; diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td index 804853d29512e..80703ad72d954 100644 --- a/clang/lib/AST/ByteCode/Opcodes.td +++ b/clang/lib/AST/ByteCode/Opcodes.td @@ -865,6 +865,7 @@ def CheckNewTypeMismatchArray : Opcode { def IsConstantContext: Opcode; def CheckAllocations : Opcode; +def CheckNull : Opcode; def BitCastTypeClass : TypeClass { let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, diff --git a/clang/test/AST/ByteCode/complex.cpp b/clang/test/AST/ByteCode/complex.cpp index 959d759005ef4..be10b3cfa53da 100644 --- a/clang/test/AST/ByteCode/complex.cpp +++ b/clang/test/AST/ByteCode/complex.cpp @@ -396,10 +396,9 @@ namespace ComplexConstexpr { // both-note {{cannot refer to element 3 of array of 2 elements}} constexpr _Complex float *p = 0; constexpr float pr = __real *p; // both-error {{constant expr}} \ - // expected-note {{read of dereferenced null pointer}} \ - // ref-note {{dereferencing a null pointer}} + // both-note {{dereferencing a null pointer}} constexpr float pi = __imag *p; // both-error {{constant expr}} \ - // ref-note {{dereferencing a null pointer}} + // both-note {{dereferencing a null pointer}} constexpr const _Complex double *q = &test3 + 1; constexpr double qr = __real *q; // ref-error {{constant expr}} \ // ref-note {{cannot access real component of pointer past the end}} diff --git a/clang/test/AST/ByteCode/cxx11.cpp b/clang/test/AST/ByteCode/cxx11.cpp index 55554220b0a8a..378702f9b3620 100644 --- a/clang/test/AST/ByteCode/cxx11.cpp +++ b/clang/test/AST/ByteCode/cxx11.cpp @@ -39,9 +39,8 @@ struct S { constexpr S s = { 5 }; constexpr const int *p = &s.m + 1; -constexpr const int *np2 = &(*(int(*)[4])nullptr)[0]; -// ref-error@-1 {{constexpr variable 'np2' must be initialized by a constant expression}} \ -// ref-note@-1 {{dereferencing a null pointer is not allowed in a constant expression}} +constexpr const int *np2 = &(*(int(*)[4])nullptr)[0]; // both-error {{constexpr variable 'np2' must be initialized by a constant expression}} \ + // both-note {{dereferencing a null pointer is not allowed in a constant expression}} constexpr int preDec(int x) { // both-error {{never produces a constant expression}} return --x; // both-note {{subexpression}} diff --git a/clang/test/AST/ByteCode/records.cpp b/clang/test/AST/ByteCode/records.cpp index 774fed6189d64..5ca3e2d12e2df 100644 --- a/clang/test/AST/ByteCode/records.cpp +++ b/clang/test/AST/ByteCode/records.cpp @@ -1660,11 +1660,9 @@ namespace NullptrCast { constexpr A *na = nullptr; constexpr B *nb = nullptr; constexpr A &ra = *nb; // both-error {{constant expression}} \ - // ref-note {{dereferencing a null pointer}} \ - // expected-note {{cannot access base class of null pointer}} + // both-note {{dereferencing a null pointer}} constexpr B &rb = (B&)*na; // both-error {{constant expression}} \ - // ref-note {{dereferencing a null pointer}} \ - // expected-note {{cannot access derived class of null pointer}} + // both-note {{dereferencing a null pointer}} constexpr bool test() { auto a = (A*)(B*)nullptr; diff --git a/clang/test/CXX/drs/cwg14xx.cpp b/clang/test/CXX/drs/cwg14xx.cpp index 8d39018d8926c..047df171afffa 100644 --- a/clang/test/CXX/drs/cwg14xx.cpp +++ b/clang/test/CXX/drs/cwg14xx.cpp @@ -6,6 +6,14 @@ // RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx11-17,since-cxx11, -fexceptions -fcxx-exceptions -pedantic-errors -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx14-17,cxx11-17,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -std=c++17 %s -verify=expected,cxx14-17,cxx11-17,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors -fexperimental-new-constant-interpreter + namespace cwg1413 { // cwg1413: 12 template<int> struct Check { typedef int type; >From fb9cd1db075664122b60edc1ad0c05984f8a3577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Sat, 19 Jul 2025 18:34:37 +0200 Subject: [PATCH 2/2] Tentative version of #149648 --- clang/lib/AST/ByteCode/Interp.h | 3 +-- clang/test/AST/ByteCode/const-eval.c | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 3d2d7be9dc0d9..7ba6e21bd5d82 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -1890,9 +1890,8 @@ inline bool CheckNull(InterpState &S, CodePtr OpPC) { if (Ptr.isZero()) { S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_dereferencing_null); - return false; + return S.noteUndefinedBehavior(); } - return true; } diff --git a/clang/test/AST/ByteCode/const-eval.c b/clang/test/AST/ByteCode/const-eval.c index eab14c08ec809..3e228226ac8c1 100644 --- a/clang/test/AST/ByteCode/const-eval.c +++ b/clang/test/AST/ByteCode/const-eval.c @@ -180,6 +180,9 @@ typedef __INTPTR_TYPE__ intptr_t; const intptr_t A = (intptr_t)(((int*) 0) + 1); const intptr_t B = (intptr_t)(((char*)0) + 3); _Static_assert(A > B, ""); +int * GH149500_p = &(*(int *)0x400); +static const void *GH149500_q = &(*(const struct sysrq_key_op *)0); + #else #error :( #endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits