diff options
author | Krystian Stasiowski <sdkrystian@gmail.com> | 2024-07-09 16:40:53 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-09 16:40:53 -0400 |
commit | 9e1f1cfa59c4513798de5c326d77e1e5912b1634 (patch) | |
tree | 2318eeaf194145f0e2127b816a653db58d0fe8c8 /clang/test | |
parent | 10f3f06d865fe5ec434fbaf78009301e95b59ea5 (diff) | |
download | llvm-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.cpp | 16 |
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'}} +} |