[clang] [clang] Reject initializing constexpr pointer variables with non-null pointers (PR #228776)

Abdulmalek Almkainzi via cfe-commits cfe-commits at lists.llvm.org
Sat Oct 3 14:36:52 PDT 2026


https://github.com/aalmkainzi created https://github.com/llvm/llvm-project/pull/228776

In `CheckLValueConstantExpression`, if we're in C23 and initializing a constexpr object, then error out if it's not a null pointer.

example:
```C
typedef struct {
    int *a;
} foo;

int b = 42;

constexpr foo bar1 = (foo){.a = &b};
constexpr foo bar2 = {.a = &b};
```
previously, only `bar2` is an error, now both are errors.

Fixes #121694


>From dd487bdfdcc50fccb07b93d4d2029e8becdcb3ea Mon Sep 17 00:00:00 2001
From: Abdulmalek Almkainzi <aalmkainzi at gmail.com>
Date: Sun, 4 Oct 2026 00:24:23 +0300
Subject: [PATCH] made CheckLValueConstantExpression return false when
 initializing constexpr pointer variable with non-null in C23

---
 clang/lib/AST/ExprConstant.cpp                    |  8 ++++++++
 clang/test/Parser/c23-reject-non-null-constexpr.c | 12 ++++++++++++
 2 files changed, 20 insertions(+)
 create mode 100644 clang/test/Parser/c23-reject-non-null-constexpr.c

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 3f295f35d1361..f40cf9e8e316b 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2175,6 +2175,14 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
                                           QualType Type, const LValue &LVal,
                                           ConstantExprKind Kind,
                                           CheckedTemporaries &CheckedTemps) {
+  if (Info.getLangOpts().C23 && !LVal.isNullPointer()) {
+    auto D = Info.EvaluatingDecl;
+    if (auto *ValD = D.dyn_cast<const ValueDecl *>())
+      if (auto *VarD = dyn_cast<VarDecl>(ValD))
+        if (VarD->isConstexpr())
+          return false;
+  }
+
   bool IsReferenceType = Type->isReferenceType();
 
   APValue::LValueBase Base = LVal.getLValueBase();
diff --git a/clang/test/Parser/c23-reject-non-null-constexpr.c b/clang/test/Parser/c23-reject-non-null-constexpr.c
new file mode 100644
index 0000000000000..148b08a7ff1f8
--- /dev/null
+++ b/clang/test/Parser/c23-reject-non-null-constexpr.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c23 -verify -pedantic %s
+
+const int a = 0;
+struct C { const int *p; };
+constexpr struct C c1 = {&a}; // expected-error{{constexpr pointer initializer is not null}}
+constexpr struct C c2 = (struct C){&a}; // expected-error{{constexpr variable 'c2' must be initialized by a constant expression}}
+
+union U { const int *p; int x; };
+constexpr union U u1 = {.p = &a}; // expected-error{{constexpr pointer initializer is not null}}
+constexpr union U u2 = (union U){.p = &a}; // expected-error{{constexpr variable 'u2' must be initialized by a constant expression}}
+constexpr union U u3 = {.x = 1};
+constexpr union U u4 = (union U){.x = 1};



More information about the cfe-commits mailing list