Author: Haojian Wu Date: 2020-03-26T08:50:33+01:00 New Revision: a9ab11d40830cc01c3a6ff97633140e8bd1e431e
URL: https://github.com/llvm/llvm-project/commit/a9ab11d40830cc01c3a6ff97633140e8bd1e431e DIFF: https://github.com/llvm/llvm-project/commit/a9ab11d40830cc01c3a6ff97633140e8bd1e431e.diff LOG: [AST] Build recovery expressions for nonexistent member exprs. Summary: Previously, we dropped the AST node for nonexistent member exprs. Reviewers: sammccall Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D76764 Added: Modified: clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp clang/lib/Parse/ParseExpr.cpp clang/test/AST/ast-dump-recovery.cpp clang/test/SemaCXX/constructor-initializer.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp index 9334d9d17608..eb4fdc98fb0b 100644 --- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp +++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp @@ -678,7 +678,7 @@ void foo() { TEST(IncludeFixerTest, NoCrashMemebrAccess) { Annotations Test(R"cpp(// error-ok struct X { int xyz; }; - void g() { X x; x.$[[xy]] } + void g() { X x; x.$[[xy]]; } )cpp"); auto TU = TestTU::withCode(Test.code()); auto Index = buildIndexWithSymbol( diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index bcd5679cb43f..4cb828cd23cc 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -2102,8 +2102,14 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { OpKind, SS, TemplateKWLoc, Name, CurParsedObjCImpl ? CurParsedObjCImpl->Dcl : nullptr); - if (!LHS.isInvalid() && Tok.is(tok::less)) - checkPotentialAngleBracket(LHS); + if (!LHS.isInvalid()) { + if (Tok.is(tok::less)) + checkPotentialAngleBracket(LHS); + } else if (OrigLHS && Name.isValid()) { + // Preserve the LHS if the RHS is an invalid member. + LHS = Actions.CreateRecoveryExpr(OrigLHS->getBeginLoc(), + Name.getEndLoc(), {OrigLHS}); + } break; } case tok::plusplus: // postfix-expression: postfix-expression '++' diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp index beb409edc4a6..9ccfc5a106f8 100644 --- a/clang/test/AST/ast-dump-recovery.cpp +++ b/clang/test/AST/ast-dump-recovery.cpp @@ -83,3 +83,18 @@ int binary = a + nullptr; // CHECK-NEXT: `-DeclRefExpr {{.*}} 'a' // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors int ternary = a ? nullptr : a; + +// CHECK: FunctionDecl +// CHECK-NEXT:|-ParmVarDecl {{.*}} x +// CHECK-NEXT:`-CompoundStmt +// CHECK-NEXT: |-RecoveryExpr {{.*}} contains-errors +// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'foo' +// CHECK-NEXT: `-CallExpr {{.*}} contains-errors +// CHECK-NEXT: |-RecoveryExpr {{.*}} contains-errors +// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'foo' +// CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' +struct Foo {} foo; +void test(int x) { + foo.abc; + foo->func(x); +} \ No newline at end of file diff --git a/clang/test/SemaCXX/constructor-initializer.cpp b/clang/test/SemaCXX/constructor-initializer.cpp index 102ff1e80d03..df8991416712 100644 --- a/clang/test/SemaCXX/constructor-initializer.cpp +++ b/clang/test/SemaCXX/constructor-initializer.cpp @@ -250,7 +250,7 @@ namespace test3 { B(const String& s, int e=0) // expected-error {{unknown type name}} : A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no matching constructor}} expected-error {{does not name}} B(const B& e) - : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{does not name}} \ + : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error 2{{does not name}} \ // expected-error {{no member named 'm_String' in 'test3::B'}} } }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits