-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang] Check null TypeSourceInfo in CreateUnaryExprOrTypeTraitExpr #112111
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
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang Author: Andrew Sukach (sookach) ChangesFixes #111594. The crash is caused by the following call We already check for a null TypeInfo when creating a UnaryExprOrTypeTraitExpr here but the following lines can, and in the case of the code in the issue, nullify the TypeInfo Thus, adding the additional check for nullptr prevents the erroneous memory access. @shafik Thoughts? Thanks Full diff: https://github.com/llvm/llvm-project/pull/112111.diff 1 Files Affected:
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 4e37385710af5e..b0bd216c5dc101 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4629,6 +4629,9 @@ ExprResult Sema::CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
TInfo->getType()->isVariablyModifiedType())
TInfo = TransformToPotentiallyEvaluated(TInfo);
+ if (!TInfo)
+ return ExprError();
+
// C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
return new (Context) UnaryExprOrTypeTraitExpr(
ExprKind, TInfo, Context.getSizeType(), OpLoc, R.getEnd());
|
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.
The implementation lgtm, but this still needs a test and a release note.
f502117
to
d7a37cb
Compare
// expected-error@3 {{a type specifier is required for all declarations}} | ||
// expected-error@3 {{use of undeclared identifier 'tree'; did you mean 'true'?}} | ||
// expected-error@3 {{member reference type 'bool' is not a pointer}} | ||
// expected-error@3 {{expected ';' after expression}} | ||
// expected-error@3 {{use of undeclared identifier 'next'; did you mean 'new'?}} | ||
// expected-error@3 {{expected expression}} | ||
// expected-error@3 {{expected ';' after expression}} | ||
// expected-error@26 {{expected '}'}} | ||
// expected-note@3 {{to match this '{'}} | ||
// expected-error@26 {{expected ')'}} | ||
// expected-note@3 {{to match this '('}} | ||
// expected-error@26 {{expected ']'}} | ||
// expected-note@3 {{to match this '['}} | ||
// expected-error@26 {{expected ')'}} | ||
// expected-note@3 {{to match this '('}} | ||
// expected-error@3 {{using declaration 'exp' instantiates to an empty pack}} | ||
// expected-error@3 {{variable has incomplete type 'struct b'}} | ||
// expected-note@3 {{forward declaration of 'b'}} | ||
// expected-error@3 {{expected ';' at end of declaration}} | ||
// expected-error@26 {{expected '}'}} | ||
// expected-note@3 {{to match this '{'}} | ||
// expected-warning@3 {{expression 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.
CC @Endilll @erichkeane Do we have a cleaner way of writing fuzzer tests? Because this is rather atrocious to look at.
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.
OOof, that is awful. Is that really the minimal example that causes the crash? I don't really have a great idea. I might disable the warning with a -Wno
flag, but most of those are not actually important to what we want to do here. The whole point is to ensure it doesn't crash/assert, not to make sure we emit all those diagnostics.
We should come up with a way to test "did not crash" instead of this.
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.
Instead of running -verify
on the test, can we just run FileCheck
and ensure there are no strings like PLEASE submit a bug report
or something?
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.
Not really, not all of the test configurations use the normal crash handler... I would hope the author could use the test as an example to come up with a minimal example that does the bare minimum to cause this issue rather than using the fuzz itself: I don't think the fuzz generated code should actually be in our test suite, just the actual use case that is required to get into this situation.
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.
Definitely agree that the test file is pretty ugly. I tried to remove some parts of the original code but none of my reductions kept the crash, so that's why I left it in full. I think ideally there would just be a way to make sure that there is no crash without checking the specific diagnostics, but it seems that option isn't available.
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.
See #78898 for the previous discussion on the matter of tests based on crash reports.
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.
In most scenarios, we really do want to use -verify
to see what the diagnostic behavior is because we want it to be very obvious when diagnostic behavior needs to be improved. (Similar for -emit-llvm
when doing codegen tests.) However, we only care about the behavior of code that a real user is likely to write, which is not typical for fuzzer-generated crashing issues. I think it would be useful to have a special -verify
mode that ignores all diagnostics (whether any are generated or not) and only tests that there was not a crash. Something like // expected-no-crash
and we diagnose if any other // expected-whatever
comments appear anywhere in the file. That should make it more clear "we're not interested in behavior beyond not crashing" for anyone reading the 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.
// expected-no-crash
would be a good name for the directive, but I'm not sure that frontend is a good place for such check layering-wise.
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.
Yeah, it seems like more of a lit
layer thing than a frontend layer thing.
So long as it's obvious that the intent of the test is "test this doesn't crash", I'm not too hung up on the syntax.
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.
At this point it seems like this is a separate issue, maybe we should open an issue for this and we can move the discussion there?
a478b5e
to
384e4eb
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.
The fix looks good to me but I guess everyone needs to be happy w/ the test first.
ping, any chance we can make progress here? |
Fixes #111594. The crash is caused by the following call
https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/ComputeDependence.cpp#L81-L82
We already check for a null TypeInfo when creating a UnaryExprOrTypeTraitExpr here
https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/SemaExpr.cpp#L4616-L4617
but the following lines can, and in the case of the code in the issue, nullify the TypeInfo
https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/SemaExpr.cpp#L4616-L4617
Thus, adding the additional check for nullptr prevents the erroneous memory access.
@shafik Thoughts? Thanks