Author: Haojian Wu
Date: 2020-09-28T15:10:00+02:00
New Revision: bf890dcb0f5eb05b1a98cbd1cdd24c0c4ece8f8d

URL: 
https://github.com/llvm/llvm-project/commit/bf890dcb0f5eb05b1a98cbd1cdd24c0c4ece8f8d
DIFF: 
https://github.com/llvm/llvm-project/commit/bf890dcb0f5eb05b1a98cbd1cdd24c0c4ece8f8d.diff

LOG: [clang] Don't emit "no member" diagnostic if the lookup fails on an 
invalid record decl.

The "no member" diagnostic is likely bogus.

Reviewed By: sammccall, #libc

Differential Revision: https://reviews.llvm.org/D86765

Added: 
    

Modified: 
    clang/lib/Sema/SemaExpr.cpp
    clang/test/SemaCXX/access-base-class.cpp
    
libcxx/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 9cd5a35660d9..a7c076657fb5 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2581,6 +2581,13 @@ ExprResult Sema::BuildQualifiedDeclarationNameExpr(
                                      NameInfo, /*TemplateArgs=*/nullptr);
 
   if (R.empty()) {
+    // Don't diagnose problems with invalid record decl, the secondary 
no_member
+    // diagnostic during template instantiation is likely bogus, e.g. if a 
class
+    // is invalid because it's derived from an invalid base class, then missing
+    // members were likely supposed to be inherited.
+    if (const auto *CD = dyn_cast<CXXRecordDecl>(DC))
+      if (CD->isInvalidDecl())
+        return ExprError();
     Diag(NameInfo.getLoc(), diag::err_no_member)
       << NameInfo.getName() << DC << SS.getRange();
     return ExprError();

diff  --git a/clang/test/SemaCXX/access-base-class.cpp 
b/clang/test/SemaCXX/access-base-class.cpp
index f676e199b6ce..2ed40ed536c5 100644
--- a/clang/test/SemaCXX/access-base-class.cpp
+++ b/clang/test/SemaCXX/access-base-class.cpp
@@ -89,3 +89,29 @@ namespace T7 {
   };
 }
 
+namespace T8 {
+template <int>
+struct flag {
+  static constexpr bool value = true;
+};
+
+template <class T>
+struct trait : flag<sizeof(T)> {};
+
+template <class T, bool Inferred = trait<T>::value>
+struct a {};
+
+template <class T>
+class b {
+  a<T> x;
+  using U = a<T>;
+};
+
+template <int>
+struct Impossible {
+  static_assert(false, ""); // expected-error {{static_assert failed}}
+};
+
+// verify "no member named 'value'" bogus diagnostic is not emitted.
+trait<b<Impossible<0>>>::value;
+} // namespace T8

diff  --git 
a/libcxx/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp
 
b/libcxx/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp
index 0bba136ade6d..5727db68629b 100644
--- 
a/libcxx/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp
+++ 
b/libcxx/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp
@@ -45,8 +45,6 @@ int main(int, char**) {
     SPtr<3> s3(nullptr, Deleter{}); // OK
   }
   // expected-error-re@memory:* 2 {{static_assert failed{{.*}} "default_delete 
cannot be instantiated for function types"}}
-  // FIXME: suppress this bogus diagnostic, see 
https://reviews.llvm.org/D86685.
-  // expected-error@memory:* 0+ {{no member named 'value' in}}
   {
     SPtr<4> s4(getFn<4>()); // expected-note {{requested here}}
     SPtr<5> s5(getFn<5>(), std::default_delete<FnType<5>>{}); // expected-note 
{{requested here}}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to