[clang] [clang] Look through parens around reinterpret_cast to emit a warning (PR #157033)

Andrew Savonichev via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 5 00:26:08 PDT 2025


https://github.com/asavonic created https://github.com/llvm/llvm-project/pull/157033

Clang warns about UB when a `reinterpret_cast` is dereferenced as an incompatible type:
```
  long l;
  *reinterpret_cast<double*>(&l) // UB
```
However, the code was too strict and did not handle extra parens around a `reinterpret_cast`, so the following case was not diagnosed:
```
  long l;
  *(reinterpret_cast<double*>(&l)) // UB, but no warning
```
The patch now skips ParenExpr when looking for a CXXReinterpretCastExpr to enable a diagnostic for the second case.

>From 099191e2b413414f82422cc56648c71febd69f20 Mon Sep 17 00:00:00 2001
From: Andrew Savonichev <andrew.savonichev at gmail.com>
Date: Fri, 5 Sep 2025 15:58:57 +0900
Subject: [PATCH] [clang] Look through parens around reinterpret_cast to emit a
 warning

Clang warns about UB when a reinterpret_cast is dereferenced as an
incompatible type:

  long l;
  *reinterpret_cast<double*>(&l) // UB

However, the code was too strict and did not handle extra parens
around a reinterpret_cast, so the following case was not diagnosed:

  long l;
  *(reinterpret_cast<double*>(&l)) // UB, but no warning

The patch now skips ParenExpr when looking for a
CXXReinterpretCastExpr to enable a diagnostic for the second case.
---
 clang/lib/Sema/SemaExpr.cpp             | 2 +-
 clang/test/SemaCXX/reinterpret-cast.cpp | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 8565b18078185..f7e02805ae9d0 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14774,7 +14774,7 @@ static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK,
   QualType OpTy = Op->getType();
   QualType Result;
 
-  if (isa<CXXReinterpretCastExpr>(Op)) {
+  if (isa<CXXReinterpretCastExpr>(Op->IgnoreParens())) {
     QualType OpOrigType = Op->IgnoreParenCasts()->getType();
     S.CheckCompatibleReinterpretCast(OpOrigType, OpTy, /*IsDereference*/true,
                                      Op->getSourceRange());
diff --git a/clang/test/SemaCXX/reinterpret-cast.cpp b/clang/test/SemaCXX/reinterpret-cast.cpp
index bfb808773b900..fdaa17a35eb8b 100644
--- a/clang/test/SemaCXX/reinterpret-cast.cpp
+++ b/clang/test/SemaCXX/reinterpret-cast.cpp
@@ -167,6 +167,9 @@ void dereference_reinterpret_cast() {
   (void)reinterpret_cast<float&>(d);  // expected-warning {{reinterpret_cast from 'double' to 'float &' has undefined behavior}}
   (void)*reinterpret_cast<float*>(&d);  // expected-warning {{dereference of type 'float *' that was reinterpret_cast from type 'double *' has undefined behavior}}
 
+  // Look through parens
+  (void)*(reinterpret_cast<double*>(&l));  // expected-warning {{dereference of type 'double *' that was reinterpret_cast from type 'long *' has undefined behavior}}
+
   // TODO: add warning for tag types
   (void)reinterpret_cast<A&>(b);
   (void)*reinterpret_cast<A*>(&b);



More information about the cfe-commits mailing list