This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
hokein marked an inline comment as done.
Closed by commit rGba6c71b1377e: [AST] Use RecoveryExpr to model a DeclRefExpr 
which refers to an invalid Decl. (authored by hokein).

Changed prior to commit:
  https://reviews.llvm.org/D120812?vs=412400&id=412632#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D120812/new/

https://reviews.llvm.org/D120812

Files:
  clang/lib/Sema/SemaExpr.cpp
  clang/test/AST/ast-dump-recovery.cpp
  clang/test/Sema/ms-inline-asm.c
  clang/test/SemaCXX/constructor-initializer.cpp
  clang/test/SemaCXX/copy-assignment.cpp


Index: clang/test/SemaCXX/copy-assignment.cpp
===================================================================
--- clang/test/SemaCXX/copy-assignment.cpp
+++ clang/test/SemaCXX/copy-assignment.cpp
@@ -114,6 +114,7 @@
 namespace test1 {
   template<typename T> class A : public unknown::X { // expected-error 
{{undeclared identifier 'unknown'}} expected-error {{expected class name}}
     A(UndeclaredType n) : X(n) {} // expected-error {{unknown type name 
'UndeclaredType'}}
+    // expected-error@-1 {{member initializer 'X' does not name a non-static 
data member or base class}}
   };
   template<typename T> class B : public A<T>     {
     virtual void foo() {}
Index: clang/test/SemaCXX/constructor-initializer.cpp
===================================================================
--- clang/test/SemaCXX/constructor-initializer.cpp
+++ clang/test/SemaCXX/constructor-initializer.cpp
@@ -249,7 +249,9 @@
   class B : public A {
   public:
     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}}
+      : A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no 
matching constructor}} \
+      expected-error {{member initializer 'm_String' does not name}} \
+      expected-error {{member initializer 'm_ErrorStr' does not name}}
     B(const B& e)
       : 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'}}
Index: clang/test/Sema/ms-inline-asm.c
===================================================================
--- clang/test/Sema/ms-inline-asm.c
+++ clang/test/Sema/ms-inline-asm.c
@@ -78,7 +78,6 @@
   __asm { mov eax, [eax] UndeclaredId } // expected-error {{unknown token in 
expression}} expected-error {{use of undeclared label 'UndeclaredId'}}
 
   // FIXME: Only emit one diagnostic here.
-  // expected-error@+3 {{use of undeclared label 'A'}}
   // expected-error@+2 {{unexpected type name 'A': expected expression}}
   // expected-error@+1 {{unknown token in expression}}
   __asm { mov eax, [eax] A }
Index: clang/test/AST/ast-dump-recovery.cpp
===================================================================
--- clang/test/AST/ast-dump-recovery.cpp
+++ clang/test/AST/ast-dump-recovery.cpp
@@ -401,3 +401,13 @@
   // CHECK-NEXT:   |-IntegerLiteral {{.*}} 'int' 7
   // CHECK-NEXT:   `-IntegerLiteral {{.*}} 'int' 8
 }
+
+void RecoveryExprForInvalidDecls(Unknown InvalidDecl) {
+  InvalidDecl + 1;
+  // CHECK:      BinaryOperator {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>'
+  // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
+  InvalidDecl();
+  // CHECK:      CallExpr {{.*}}
+  // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>'
+}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -3228,8 +3228,12 @@
          "Cannot refer unambiguously to a function template");
 
   SourceLocation Loc = NameInfo.getLoc();
-  if (CheckDeclInExpr(*this, Loc, D))
-    return ExprError();
+  if (CheckDeclInExpr(*this, Loc, D)) {
+    // Recovery from invalid cases (e.g. D is an invalid Decl).
+    // We use the dependent type for the RecoveryExpr to prevent bogus 
follow-up
+    // diagnostics, as invalid decls use int as a fallback type.
+    return CreateRecoveryExpr(NameInfo.getBeginLoc(), NameInfo.getEndLoc(), 
{});
+  }
 
   if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) {
     // Specifically diagnose references to class templates that are missing


Index: clang/test/SemaCXX/copy-assignment.cpp
===================================================================
--- clang/test/SemaCXX/copy-assignment.cpp
+++ clang/test/SemaCXX/copy-assignment.cpp
@@ -114,6 +114,7 @@
 namespace test1 {
   template<typename T> class A : public unknown::X { // expected-error {{undeclared identifier 'unknown'}} expected-error {{expected class name}}
     A(UndeclaredType n) : X(n) {} // expected-error {{unknown type name 'UndeclaredType'}}
+    // expected-error@-1 {{member initializer 'X' does not name a non-static data member or base class}}
   };
   template<typename T> class B : public A<T>     {
     virtual void foo() {}
Index: clang/test/SemaCXX/constructor-initializer.cpp
===================================================================
--- clang/test/SemaCXX/constructor-initializer.cpp
+++ clang/test/SemaCXX/constructor-initializer.cpp
@@ -249,7 +249,9 @@
   class B : public A {
   public:
     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}}
+      : A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no matching constructor}} \
+      expected-error {{member initializer 'm_String' does not name}} \
+      expected-error {{member initializer 'm_ErrorStr' does not name}}
     B(const B& e)
       : 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'}}
Index: clang/test/Sema/ms-inline-asm.c
===================================================================
--- clang/test/Sema/ms-inline-asm.c
+++ clang/test/Sema/ms-inline-asm.c
@@ -78,7 +78,6 @@
   __asm { mov eax, [eax] UndeclaredId } // expected-error {{unknown token in expression}} expected-error {{use of undeclared label 'UndeclaredId'}}
 
   // FIXME: Only emit one diagnostic here.
-  // expected-error@+3 {{use of undeclared label 'A'}}
   // expected-error@+2 {{unexpected type name 'A': expected expression}}
   // expected-error@+1 {{unknown token in expression}}
   __asm { mov eax, [eax] A }
Index: clang/test/AST/ast-dump-recovery.cpp
===================================================================
--- clang/test/AST/ast-dump-recovery.cpp
+++ clang/test/AST/ast-dump-recovery.cpp
@@ -401,3 +401,13 @@
   // CHECK-NEXT:   |-IntegerLiteral {{.*}} 'int' 7
   // CHECK-NEXT:   `-IntegerLiteral {{.*}} 'int' 8
 }
+
+void RecoveryExprForInvalidDecls(Unknown InvalidDecl) {
+  InvalidDecl + 1;
+  // CHECK:      BinaryOperator {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>'
+  // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
+  InvalidDecl();
+  // CHECK:      CallExpr {{.*}}
+  // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>'
+}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -3228,8 +3228,12 @@
          "Cannot refer unambiguously to a function template");
 
   SourceLocation Loc = NameInfo.getLoc();
-  if (CheckDeclInExpr(*this, Loc, D))
-    return ExprError();
+  if (CheckDeclInExpr(*this, Loc, D)) {
+    // Recovery from invalid cases (e.g. D is an invalid Decl).
+    // We use the dependent type for the RecoveryExpr to prevent bogus follow-up
+    // diagnostics, as invalid decls use int as a fallback type.
+    return CreateRecoveryExpr(NameInfo.getBeginLoc(), NameInfo.getEndLoc(), {});
+  }
 
   if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) {
     // Specifically diagnose references to class templates that are missing
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to