Skip to content

Commit ccea1fc

Browse files
committed
[clang][bytecode] Diagnose dereferencing a null pointer
1 parent fe19419 commit ccea1fc

File tree

7 files changed

+29
-10
lines changed

7 files changed

+29
-10
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6375,6 +6375,9 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
63756375
if (!this->visit(SubExpr))
63766376
return false;
63776377

6378+
if (!this->emitCheckNull(E))
6379+
return false;
6380+
63786381
if (classifyPrim(SubExpr) == PT_Ptr)
63796382
return this->emitNarrowPtr(E);
63806383
return true;

clang/lib/AST/ByteCode/Interp.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1885,6 +1885,17 @@ inline bool Dump(InterpState &S, CodePtr OpPC) {
18851885
return true;
18861886
}
18871887

1888+
inline bool CheckNull(InterpState &S, CodePtr OpPC) {
1889+
const auto &Ptr = S.Stk.peek<Pointer>();
1890+
if (Ptr.isZero()) {
1891+
S.FFDiag(S.Current->getSource(OpPC),
1892+
diag::note_constexpr_dereferencing_null);
1893+
return false;
1894+
}
1895+
1896+
return true;
1897+
}
1898+
18881899
inline bool VirtBaseHelper(InterpState &S, CodePtr OpPC, const RecordDecl *Decl,
18891900
const Pointer &Ptr) {
18901901
Pointer Base = Ptr;

clang/lib/AST/ByteCode/Opcodes.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,7 @@ def CheckNewTypeMismatchArray : Opcode {
865865

866866
def IsConstantContext: Opcode;
867867
def CheckAllocations : Opcode;
868+
def CheckNull : Opcode;
868869

869870
def BitCastTypeClass : TypeClass {
870871
let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64,

clang/test/AST/ByteCode/complex.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -396,10 +396,9 @@ namespace ComplexConstexpr {
396396
// both-note {{cannot refer to element 3 of array of 2 elements}}
397397
constexpr _Complex float *p = 0;
398398
constexpr float pr = __real *p; // both-error {{constant expr}} \
399-
// expected-note {{read of dereferenced null pointer}} \
400-
// ref-note {{dereferencing a null pointer}}
399+
// both-note {{dereferencing a null pointer}}
401400
constexpr float pi = __imag *p; // both-error {{constant expr}} \
402-
// ref-note {{dereferencing a null pointer}}
401+
// both-note {{dereferencing a null pointer}}
403402
constexpr const _Complex double *q = &test3 + 1;
404403
constexpr double qr = __real *q; // ref-error {{constant expr}} \
405404
// ref-note {{cannot access real component of pointer past the end}}

clang/test/AST/ByteCode/cxx11.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,8 @@ struct S {
3939
constexpr S s = { 5 };
4040
constexpr const int *p = &s.m + 1;
4141

42-
constexpr const int *np2 = &(*(int(*)[4])nullptr)[0];
43-
// ref-error@-1 {{constexpr variable 'np2' must be initialized by a constant expression}} \
44-
// ref-note@-1 {{dereferencing a null pointer is not allowed in a constant expression}}
42+
constexpr const int *np2 = &(*(int(*)[4])nullptr)[0]; // both-error {{constexpr variable 'np2' must be initialized by a constant expression}} \
43+
// both-note {{dereferencing a null pointer is not allowed in a constant expression}}
4544

4645
constexpr int preDec(int x) { // both-error {{never produces a constant expression}}
4746
return --x; // both-note {{subexpression}}

clang/test/AST/ByteCode/records.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,11 +1660,9 @@ namespace NullptrCast {
16601660
constexpr A *na = nullptr;
16611661
constexpr B *nb = nullptr;
16621662
constexpr A &ra = *nb; // both-error {{constant expression}} \
1663-
// ref-note {{dereferencing a null pointer}} \
1664-
// expected-note {{cannot access base class of null pointer}}
1663+
// both-note {{dereferencing a null pointer}}
16651664
constexpr B &rb = (B&)*na; // both-error {{constant expression}} \
1666-
// ref-note {{dereferencing a null pointer}} \
1667-
// expected-note {{cannot access derived class of null pointer}}
1665+
// both-note {{dereferencing a null pointer}}
16681666
constexpr bool test() {
16691667
auto a = (A*)(B*)nullptr;
16701668

clang/test/CXX/drs/cwg14xx.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@
66
// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
77
// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
88

9+
// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -fexperimental-new-constant-interpreter
10+
// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx11-17,since-cxx11, -fexceptions -fcxx-exceptions -pedantic-errors -fexperimental-new-constant-interpreter
11+
// 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
12+
// 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
13+
// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors -fexperimental-new-constant-interpreter
14+
// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors -fexperimental-new-constant-interpreter
15+
// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors -fexperimental-new-constant-interpreter
16+
917
namespace cwg1413 { // cwg1413: 12
1018
template<int> struct Check {
1119
typedef int type;

0 commit comments

Comments
 (0)