-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[Clang] fix range calculation for conditionals with throw expressions #112081
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
@llvm/pr-subscribers-clang Author: Oleksandr T. (a-tarasyuk) ChangesFixes #111854 Full diff: https://github.com/llvm/llvm-project/pull/112081.diff 3 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 337e3fc10bf49d..2ab13640bfa53c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -512,6 +512,7 @@ Bug Fixes to C++ Support
and undeclared templates. (#GH107047, #GH49093)
- Clang no longer crashes when a lambda contains an invalid block declaration that contains an unexpanded
parameter pack. (#GH109148)
+- Fixed assertion failure in range calculations for conditional throw expressions (#GH111854)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2bcb930acdcb57..b3d88f053872c1 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -9827,6 +9827,9 @@ static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth,
return IntRange(BitField->getBitWidthValue(C),
BitField->getType()->isUnsignedIntegerOrEnumerationType());
+ if (GetExprType(E)->isVoidType())
+ return IntRange{0, true};
+
return IntRange::forValueOfType(C, GetExprType(E));
}
diff --git a/clang/test/SemaCXX/conditional-expr.cpp b/clang/test/SemaCXX/conditional-expr.cpp
index 01effaa189322b..8f17555fd806ff 100644
--- a/clang/test/SemaCXX/conditional-expr.cpp
+++ b/clang/test/SemaCXX/conditional-expr.cpp
@@ -429,3 +429,10 @@ void g() {
long e = a = b ? throw 0 : throw 1;
}
} // namespace PR46484
+
+namespace GH111854 {
+void f() {
+ (true ? throw 0 : 0) <= 0; // expected-warning {{relational comparison result unused}}
+ (false ? 0 : throw 0) <= 0; // expected-warning {{relational comparison result unused}}
+}
+}
|
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.
After answering my questions this makes sense to me but I want a second set of eyes.
clang/lib/Sema/SemaChecking.cpp
Outdated
@@ -9827,6 +9827,9 @@ static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth, | |||
return IntRange(BitField->getBitWidthValue(C), | |||
BitField->getType()->isUnsignedIntegerOrEnumerationType()); | |||
|
|||
if (GetExprType(E)->isVoidType()) | |||
return IntRange{0, true}; |
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 think these changes are fine as-is, but I do wonder if a cleaner model for us to aim for is to make the return value std::optional
and return no valid object in this case; a void expression has no values it can take, and that's different than a value range of [0,0].
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.
@AaronBallman thanks for the feedback. Do you mean the following changes?
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.
@erichkeane @shafik @AaronBallman when you have a moment, could you review these changes? 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.
@AaronBallman @shafik if these changes look good to you, would you mind proceeding with the merge? thanks
… expression evaluation
f3b11c8
to
3d1ed95
Compare
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.
Update comment, else LGTM.
@a-tarasyuk do you need us to merge that for you? |
@cor3ntin yes, I do. I don't have permission to merge. thanks |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/41/builds/3058 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/4/builds/3185 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/55/builds/3165 Here is the relevant piece of the build log for the reference
|
The sanitizer failures are likely unrelated to this, but the self-build of the Flang sources might be? Do we have evidence of those failing on other commits? |
…llvm#112081) Fixes llvm#111854 --- The issue arises when `GetExprRange` encounters a `ConditionalOperator` with a `CXXThrowExpr` ```md ConditionalOperator 0x1108658e0 'int' |-CXXBoolLiteralExpr 0x110865878 '_Bool' true |-CXXThrowExpr 0x1108658a8 'void' | `-IntegerLiteral 0x110865888 'int' 0 `-IntegerLiteral 0x1108658c0 'int' 0 ``` https://github.com/llvm/llvm-project/blob/ed3d05178274890fb804f43ae1bcdfd33b5fd8f0/clang/lib/Sema/SemaChecking.cpp#L9628-L9631 The current behavior causes the `GetExprRange` to proceed with the throw expression (`CO->getTrueExpr()`/`void` type)
Fixes #111854
The issue arises when
GetExprRange
encounters aConditionalOperator
with aCXXThrowExpr
ConditionalOperator 0x1108658e0 'int' |-CXXBoolLiteralExpr 0x110865878 '_Bool' true |-CXXThrowExpr 0x1108658a8 'void' | `-IntegerLiteral 0x110865888 'int' 0 `-IntegerLiteral 0x1108658c0 'int' 0
llvm-project/clang/lib/Sema/SemaChecking.cpp
Lines 9628 to 9631 in ed3d051
The current behavior causes the
GetExprRange
to proceed with the throw expression (CO->getTrueExpr()
/void
type)