-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
[Clang][AST] Fix crash in APValue::LValueBase::getType when we have invalid decl #75130
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang Author: Shafik Yaghmour (shafik) ChangesIn some cases when calling APValue::LValueBase::getType() when we have a ValueDecl in some cases we don't handle invalid decls. We iterating over redeclarations we reset the current decl to the current most recent decl and we check the next redeclaration to ensure it is not invalid. Fixes: #69468 Full diff: https://github.com/llvm/llvm-project/pull/75130.diff 2 Files Affected:
diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
index 4eae308ef5b34..2ccd83a1d4823 100644
--- a/clang/lib/AST/APValue.cpp
+++ b/clang/lib/AST/APValue.cpp
@@ -70,11 +70,13 @@ QualType APValue::LValueBase::getType() const {
// constexpr int *p = &arr[1]; // valid?
//
// For now, we take the most complete type we can find.
- for (auto *Redecl = cast<ValueDecl>(D->getMostRecentDecl()); Redecl;
+ for (auto *Redecl = cast<ValueDecl>(D->getMostRecentDecl());
+ Redecl && !Redecl->isInvalidDecl();
Redecl = cast_or_null<ValueDecl>(Redecl->getPreviousDecl())) {
QualType T = Redecl->getType();
if (!T->isIncompleteArrayType())
return T;
+ D = Redecl;
}
return D->getType();
}
diff --git a/clang/test/AST/gh69468.cpp b/clang/test/AST/gh69468.cpp
new file mode 100644
index 0000000000000..8c93fa5e828ac
--- /dev/null
+++ b/clang/test/AST/gh69468.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -verify %s
+
+
+a[i] = b[i]; // expected-error {{use of undeclared identifier 'i'}} \
+ // expected-error {{a type specifier is required for all declarations}} \
+ // expected-error {{use of undeclared identifier 'b'}} \
+ // expected-error {{use of undeclared identifier 'i'}}
+extern char b[];
+extern char a[];
+
+void foo(int j) {
+ // This used to crash here
+ a[j] = b[j];
+}
|
6e056be
to
8a16983
Compare
…nvalid decl In some cases when calling APValue::LValueBase::getType() when we have a ValueDecl in some cases we don't handle invalid decls. We iterating over redeclarations we reset the current decl to the current most recent decl and we check the next redeclaration to ensure it is not invalid. Fixes: llvm#69468
8a16983
to
fb0ea87
Compare
@@ -70,11 +70,13 @@ QualType APValue::LValueBase::getType() const { | |||
// constexpr int *p = &arr[1]; // valid? | |||
// | |||
// For now, we take the most complete type we can find. | |||
for (auto *Redecl = cast<ValueDecl>(D->getMostRecentDecl()); Redecl; | |||
for (auto *Redecl = cast<ValueDecl>(D->getMostRecentDecl()); | |||
Redecl && !Redecl->isInvalidDecl(); |
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.
This doesn't seem right to me... this change makes us skip the 'right' answer when there is a redecl in the way.
In reality, I wonder if this whole loop is misguided. If we want to just find the 'last' non-incomplete-array-type, that search is pretty easy by looping through 'redecls'. I THINK this ends up better as:
QualType T = D->getMostRecentDecl()->getType();
for (const auto *R : D->redecls()) { // unsure if this needs to be 'getMostRecentDecl?'
if (!R->isInvalidDecl() && !R->getType()->isIncompleteArrayType())
T = R->getType();
}
return T;
redecl_iterator
is a forward-iterator, else I'd suggest just doing an rbegin/rend type thing on them.
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.
We are dealing with ill-formed code here. So there is not "right answer", right? Are you saying that we might misdiagnose an error?
Or are you saying the original code is incorrect and you think there is well-formed code we will not do the correct thing on?
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 problem is that if the 'invalid' decl is the last one, we end up giving up on this loop entirely. If the purpose here is to just skip an invalid decl, we probably need to skip JUST it, not all previous ones too.
In some cases when calling APValue::LValueBase::getType() when we have a ValueDecl in some cases we don't handle invalid decls. We iterating over redeclarations we reset the current decl to the current most recent decl and we check the next redeclaration to ensure it is not invalid.
Fixes: #69468