-
Notifications
You must be signed in to change notification settings - Fork 15k
[clang] Look through parens around reinterpret_cast to emit a warning #157033
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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.
@llvm/pr-subscribers-clang Author: Andrew Savonichev (asavonic) ChangesClang warns about UB when a
However, the code was too strict and did not handle extra parens around a
The patch now skips ParenExpr when looking for a CXXReinterpretCastExpr to enable a diagnostic for the second case. Full diff: https://github.com/llvm/llvm-project/pull/157033.diff 2 Files Affected:
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);
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a release note.
@@ -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}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am assuming this ignores multiple parens, maybe worth a test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, added a test.
b834be0
to
059fe2b
Compare
Thanks! Done. |
Clang warns about UB when a
reinterpret_cast
is dereferenced as an incompatible type:However, the code was too strict and did not handle extra parens around a
reinterpret_cast
, so the following case was not diagnosed:The patch now skips ParenExpr when looking for a CXXReinterpretCastExpr to enable a diagnostic for the second case.