Skip to content

Commit 3ade874

Browse files
authored
[clang] Look through parens around reinterpret_cast to emit a warning (#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.
1 parent 40e85fc commit 3ade874

File tree

3 files changed

+7
-1
lines changed

3 files changed

+7
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ Improvements to Clang's diagnostics
283283
pointers under ``-Wthread-safety-beta`` (still experimental), which reduces
284284
both false positives but also false negatives through more precise analysis.
285285

286+
- Clang now looks through parenthesis for ``-Wundefined-reinterpret-cast`` diagnostic.
287+
286288
Improvements to Clang's time-trace
287289
----------------------------------
288290

clang/lib/Sema/SemaExpr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14784,7 +14784,7 @@ static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK,
1478414784
QualType OpTy = Op->getType();
1478514785
QualType Result;
1478614786

14787-
if (isa<CXXReinterpretCastExpr>(Op)) {
14787+
if (isa<CXXReinterpretCastExpr>(Op->IgnoreParens())) {
1478814788
QualType OpOrigType = Op->IgnoreParenCasts()->getType();
1478914789
S.CheckCompatibleReinterpretCast(OpOrigType, OpTy, /*IsDereference*/true,
1479014790
Op->getSourceRange());

clang/test/SemaCXX/reinterpret-cast.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@ void dereference_reinterpret_cast() {
167167
(void)reinterpret_cast<float&>(d); // expected-warning {{reinterpret_cast from 'double' to 'float &' has undefined behavior}}
168168
(void)*reinterpret_cast<float*>(&d); // expected-warning {{dereference of type 'float *' that was reinterpret_cast from type 'double *' has undefined behavior}}
169169

170+
// Look through parens
171+
(void)*(reinterpret_cast<double*>(&l)); // expected-warning {{dereference of type 'double *' that was reinterpret_cast from type 'long *' has undefined behavior}}
172+
(void)*((reinterpret_cast<double*>((&l)))); // expected-warning {{dereference of type 'double *' that was reinterpret_cast from type 'long *' has undefined behavior}}
173+
170174
// TODO: add warning for tag types
171175
(void)reinterpret_cast<A&>(b);
172176
(void)*reinterpret_cast<A*>(&b);

0 commit comments

Comments
 (0)