aboutsummaryrefslogtreecommitdiff
path: root/clang/test
diff options
context:
space:
mode:
authorKrystian Stasiowski <sdkrystian@gmail.com>2024-07-09 16:40:53 -0400
committerGitHub <noreply@github.com>2024-07-09 16:40:53 -0400
commit9e1f1cfa59c4513798de5c326d77e1e5912b1634 (patch)
tree2318eeaf194145f0e2127b816a653db58d0fe8c8 /clang/test
parent10f3f06d865fe5ec434fbaf78009301e95b59ea5 (diff)
downloadllvm-9e1f1cfa59c4513798de5c326d77e1e5912b1634.zip
llvm-9e1f1cfa59c4513798de5c326d77e1e5912b1634.tar.gz
llvm-9e1f1cfa59c4513798de5c326d77e1e5912b1634.tar.bz2
[Clang][Sema] Handle class member access expressions with valid nested-name-specifiers that become invalid after lookup (#98167)
The following code causes an assert in `SemaExprMember.cpp` on line 981 to fail: ``` struct A { }; struct B; void f(A *x) { x->B::y; // crash here } ``` This happens because we only return early from `BuildMemberReferenceExpr` when the `CXXScopeSpecifier` is invalid _before_ the lookup is performed. Since the lookup may invalidate the `CXXScopeSpecifier` (e.g. if the _nested-name-specifier_ is incomplete), this results in the second `BuildMemberReferenceExpr` overload being called with an invalid `CXXScopeSpecifier`, which causes the assert to fail. This patch moves the early return for invalid `CXXScopeSpecifiers` to occur _after_ lookup is performed. This fixes #92972. I also removed the `if (SS.isSet() && SS.isInvalid())` check in `ActOnMemberAccessExpr` because the condition can never be true (`isSet` returns `getScopeRep() != nullptr` and `isInvalid` returns `Range.isValid() && getScopeRep() == nullptr`).
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CXX/basic/basic.lookup/basic.lookup.qual/basic.lookup.qual.general/p2.cpp16
1 files changed, 16 insertions, 0 deletions
diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/basic.lookup.qual.general/p2.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/basic.lookup.qual.general/p2.cpp
new file mode 100644
index 0000000..ebdae97
--- /dev/null
+++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/basic.lookup.qual.general/p2.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -verify -Wno-unused %s
+
+struct A {
+ int y;
+};
+
+struct B; // expected-note 4{{forward declaration of 'B'}}
+
+void f(A *a, B *b) {
+ a->B::x; // expected-error {{incomplete type 'B' named in nested name specifier}}
+ a->A::x; // expected-error {{no member named 'x' in 'A'}}
+ a->A::y;
+ b->B::x; // expected-error {{member access into incomplete type 'B'}}
+ b->A::x; // expected-error {{member access into incomplete type 'B'}}
+ b->A::y; // expected-error {{member access into incomplete type 'B'}}
+}