aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrystian Stasiowski <sdkrystian@gmail.com>2024-07-09 13:30:55 -0400
committerGitHub <noreply@github.com>2024-07-09 13:30:55 -0400
commitdfc8004d0b0b85155dad0e9aca84716425b87676 (patch)
tree09bfea2967e024a467b377369c74979033c98916
parentd9e4f2cba8171807f6d2a6ddc615ccb902a20a5f (diff)
downloadllvm-dfc8004d0b0b85155dad0e9aca84716425b87676.zip
llvm-dfc8004d0b0b85155dad0e9aca84716425b87676.tar.gz
llvm-dfc8004d0b0b85155dad0e9aca84716425b87676.tar.bz2
[Clang][Sema] Fix crash when rebuilding MemberExprs with invalid object expressions (#97455)
This patch fixes an assertion failure which occurs when the object expression of a `MemberExpr` is transformed into an expression with a dependent type for which the `DeclContext` cannot be computed (e.g. a `RecoveryExpr`). Fixes #95778.
-rw-r--r--clang/lib/Sema/TreeTransform.h3
-rw-r--r--clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp31
2 files changed, 34 insertions, 0 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 4450eba..d26c5a9 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -2896,6 +2896,9 @@ public:
SS.Adopt(QualifierLoc);
Base = BaseResult.get();
+ if (Base->containsErrors())
+ return ExprError();
+
QualType BaseType = Base->getType();
if (isArrow && !BaseType->isPointerType())
diff --git a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
index 982e537..f32f49e 100644
--- a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
+++ b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
@@ -574,3 +574,34 @@ namespace N4 {
}
};
} // namespace N4
+
+namespace N5 {
+ struct A {
+ int x;
+ };
+
+ template<typename T>
+ void f() {
+ A y = T::x; // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
+ y.x;
+ }
+
+ template void f<int>(); // expected-note {{in instantiation of}}
+
+ struct B {
+ template<typename T>
+ B(T&&);
+
+ int x;
+ };
+
+ template<typename T>
+ void g(T y) {
+ B z([&]() { // expected-note {{while substituting into a lambda expression here}}
+ h(&y); // expected-error {{use of undeclared identifier 'h'}}
+ });
+ z.x;
+ }
+
+ template void g(int); // expected-note {{in instantiation of}}
+} // namespace N5