EricWF created this revision.
EricWF added reviewers: rsmith, majnemer, aaron.ballman.
EricWF added a subscriber: cfe-commits.

Once a base class has been made invalid (by a static_assert for example) all 
using-member declarations in the derived classes will result in a "not a base 
class" diagnostic. This diagnostic is very misleading and should not be emitted.

This change is needed to help libc++ produce reasonable diagnostics in 
`std::optional` and `std::variant`.


https://reviews.llvm.org/D25430

Files:
  lib/Sema/SemaDeclCXX.cpp
  test/SemaCXX/using-decl-templates.cpp


Index: test/SemaCXX/using-decl-templates.cpp
===================================================================
--- test/SemaCXX/using-decl-templates.cpp
+++ test/SemaCXX/using-decl-templates.cpp
@@ -92,3 +92,17 @@
 
   template struct APtr<int>; // expected-error{{elaborated type refers to a 
type alias template}}
 }
+
+namespace DontDiagnoseInvalidTest {
+template <class> struct False { enum { value = 0 }; };
+template <class T> struct Base {
+  static_assert(False<T>::value, ""); // expected-error {{static_assert 
failed}}
+  T value;
+};
+template <class T>
+struct Derived : Base<T> { // expected-note {{requested here}}
+  using Base<T>::Base; // OK. Don't diagnose that 'Base' isn't a base class of 
Derived.
+};
+template struct Derived<int>; // expected-note {{requested here}}
+
+} // namespace DontDiagnoseInvalidTest
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -9462,11 +9462,13 @@
         return true;
       }
 
-      Diag(SS.getRange().getBegin(),
-           diag::err_using_decl_nested_name_specifier_is_not_base_class)
-        << SS.getScopeRep()
-        << cast<CXXRecordDecl>(CurContext)
-        << SS.getRange();
+      if (!cast<CXXRecordDecl>(NamedContext)->isInvalidDecl()) {
+        Diag(SS.getRange().getBegin(),
+             diag::err_using_decl_nested_name_specifier_is_not_base_class)
+          << SS.getScopeRep()
+          << cast<CXXRecordDecl>(CurContext)
+          << SS.getRange();
+      }
       return true;
     }
 


Index: test/SemaCXX/using-decl-templates.cpp
===================================================================
--- test/SemaCXX/using-decl-templates.cpp
+++ test/SemaCXX/using-decl-templates.cpp
@@ -92,3 +92,17 @@
 
   template struct APtr<int>; // expected-error{{elaborated type refers to a type alias template}}
 }
+
+namespace DontDiagnoseInvalidTest {
+template <class> struct False { enum { value = 0 }; };
+template <class T> struct Base {
+  static_assert(False<T>::value, ""); // expected-error {{static_assert failed}}
+  T value;
+};
+template <class T>
+struct Derived : Base<T> { // expected-note {{requested here}}
+  using Base<T>::Base; // OK. Don't diagnose that 'Base' isn't a base class of Derived.
+};
+template struct Derived<int>; // expected-note {{requested here}}
+
+} // namespace DontDiagnoseInvalidTest
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -9462,11 +9462,13 @@
         return true;
       }
 
-      Diag(SS.getRange().getBegin(),
-           diag::err_using_decl_nested_name_specifier_is_not_base_class)
-        << SS.getScopeRep()
-        << cast<CXXRecordDecl>(CurContext)
-        << SS.getRange();
+      if (!cast<CXXRecordDecl>(NamedContext)->isInvalidDecl()) {
+        Diag(SS.getRange().getBegin(),
+             diag::err_using_decl_nested_name_specifier_is_not_base_class)
+          << SS.getScopeRep()
+          << cast<CXXRecordDecl>(CurContext)
+          << SS.getRange();
+      }
       return true;
     }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to