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

via cfe-commits cfe-commits at lists.llvm.org
Sat Oct 3 14:37:45 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Abdulmalek Almkainzi (aalmkainzi)

<details>
<summary>Changes</summary>

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


---
Full diff: https://github.com/llvm/llvm-project/pull/228776.diff


2 Files Affected:

- (modified) clang/lib/AST/ExprConstant.cpp (+8) 
- (added) clang/test/Parser/c23-reject-non-null-constexpr.c (+12) 


``````````diff
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 3f295f35d1361a..f40cf9e8e316b9 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 00000000000000..148b08a7ff1f8c
--- /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};

``````````

</details>


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


More information about the cfe-commits mailing list