[clang] [clang][Interp] Fix nullptr array dereferencing (PR #75798)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 18 06:15:24 PST 2023


https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/75798

The attached test case would cause an assertion failure in Pointer.h when operating on a null pointer.

>From 3367734775e1624521c5e0cab41072f8ba7a53ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Mon, 18 Dec 2023 15:00:44 +0100
Subject: [PATCH] [clang][Interp] Fix nullptr array dereferencing

The attached test case would cause an assertion failure in
Pointer.h when operating on a null pointer.
---
 clang/lib/AST/Interp/Interp.cpp  | 4 ++--
 clang/lib/AST/Interp/Interp.h    | 6 ------
 clang/test/AST/Interp/arrays.cpp | 8 ++++++++
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index a82d1c3c7c622a..21ea2503b94bff 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -290,10 +290,10 @@ bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
 }
 
 bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
-  if (!CheckDummy(S, OpPC, Ptr))
-    return false;
   if (!CheckLive(S, OpPC, Ptr, AK_Read))
     return false;
+  if (!CheckDummy(S, OpPC, Ptr))
+    return false;
   if (!CheckExtern(S, OpPC, Ptr))
     return false;
   if (!CheckRange(S, OpPC, Ptr, AK_Read))
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index a240d74d63425e..2923916cd513eb 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1814,9 +1814,6 @@ inline bool ArrayElemPtr(InterpState &S, CodePtr OpPC) {
   const T &Offset = S.Stk.pop<T>();
   const Pointer &Ptr = S.Stk.peek<Pointer>();
 
-  if (!CheckArray(S, OpPC, Ptr))
-    return false;
-
   if (!OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr))
     return false;
 
@@ -1844,9 +1841,6 @@ inline bool ArrayElemPtrPop(InterpState &S, CodePtr OpPC) {
   const T &Offset = S.Stk.pop<T>();
   const Pointer &Ptr = S.Stk.pop<Pointer>();
 
-  if (!CheckArray(S, OpPC, Ptr))
-    return false;
-
   if (!OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr))
     return false;
 
diff --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp
index c455731e76699f..4aa10da55dd3ae 100644
--- a/clang/test/AST/Interp/arrays.cpp
+++ b/clang/test/AST/Interp/arrays.cpp
@@ -72,6 +72,14 @@ constexpr int getElementFromEnd(const int *Arr, int size, int index) {
 static_assert(getElementFromEnd(data, 5, 0) == 1, "");
 static_assert(getElementFromEnd(data, 5, 4) == 5, "");
 
+constexpr int getFirstElem(const int *a) {
+  return a[0]; // expected-note {{read of dereferenced null pointer}} \
+               // ref-note {{read of dereferenced null pointer}}
+}
+static_assert(getFirstElem(nullptr) == 1, ""); // expected-error {{not an integral constant expression}} \
+                                               // expected-note {{in call to}} \
+                                               // ref-error {{not an integral constant expression}} \
+                                               // ref-note {{in call to}}
 
 constexpr static int arr[2] = {1,2};
 constexpr static int arr2[2] = {3,4};



More information about the cfe-commits mailing list