[PATCH] D40566: Check if MemberExpr arguments are type-dependent.

Matt Davis via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 28 09:26:34 PST 2017


mattd created this revision.

Fixes: PR28290

When checking an argument list, arguments from the templated class instance, were
returning 'is dependent' based on the 'this' pointer. In that case, arguments were
being marked dependent, and name lookup was delayed until template instantiation. This
had the side-effect of -fdelayed-template-parsing in certain cases
(attached test case), when that should not have been the case, especially
since that flag was never passed.

According to the standard the referenced member's type needs
to be checked:

[temp.dep.expr]p5:
A class member access expression (5.2.5) is type-dependent if the expression
refers to a member of the current instantiation and the type of the referenced
member is dependent, or the class member access expression refers to a member
of an unknown specialization.

This change decides if the argument belongs to a MemberExpr. If so, then the
type of the expression is checked if it is dependent or not.


https://reviews.llvm.org/D40566

Files:
  lib/AST/Expr.cpp
  test/CXX/class.access/class.access.dcl/p1.cpp
  test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp
  test/SemaTemplate/template-with-invalid-decl.cpp


Index: test/SemaTemplate/template-with-invalid-decl.cpp
===================================================================
--- test/SemaTemplate/template-with-invalid-decl.cpp
+++ test/SemaTemplate/template-with-invalid-decl.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -verify %s
+
+class UBS;
+
+template <bool bCS> struct FIBH 
+{
+  FIBH() { GDN(BS); } // expected-error {{use of undeclared identifier 'GDN'}}
+  class UBS* BS;
+};
+
+extern void foo()
+{
+  FIBH<false> IBH;
+}
+
+extern void GDN(UBS* BS);
Index: test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp
===================================================================
--- test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp
+++ test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp
@@ -29,7 +29,7 @@
   };
 }
 
-struct Opaque0 {};
+struct Opaque0 {}; // expected-note-re 1-2{{candidate constructor {{.*}}}}
 
 namespace test1 {
   struct A {
@@ -112,7 +112,7 @@
     }
 
     void test5() {
-      Opaque0 _ = hiding;
+      Opaque0 _ = hiding; // expected-error {{no viable conversion from 'int' to 'Opaque0'}}
     }
   };
 }
Index: test/CXX/class.access/class.access.dcl/p1.cpp
===================================================================
--- test/CXX/class.access/class.access.dcl/p1.cpp
+++ test/CXX/class.access/class.access.dcl/p1.cpp
@@ -56,7 +56,7 @@
   };
 }
 
-struct Opaque0 {};
+struct Opaque0 {}; // expected-note-re 1-2 {{candidate constructor {{.*}}}}
 
 namespace test1 {
   struct A {
@@ -196,7 +196,7 @@
     }
 
     void test5() {
-      Opaque0 _ = hiding;
+      Opaque0 _ = hiding; // expected-error {{no viable conversion from 'int' to 'Opaque0'}}
     }
   };
 }
Index: lib/AST/Expr.cpp
===================================================================
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -2738,12 +2738,27 @@
   return false;
 }
 
+/// \brief Returns true if the expression is a MemberExpr
+/// with a dependent type.
+static bool isDependentMember(const Expr *E)
+{
+  if (const auto ME = dyn_cast_or_null<MemberExpr>(E))
+    if (const auto Member = ME->getMemberDecl())
+      return Member->getType()->isDependentType();
+
+  return false;
+}
+
 /// hasAnyTypeDependentArguments - Determines if any of the expressions
 /// in Exprs is type-dependent.
 bool Expr::hasAnyTypeDependentArguments(ArrayRef<Expr *> Exprs) {
-  for (unsigned I = 0; I < Exprs.size(); ++I)
-    if (Exprs[I]->isTypeDependent())
+  for (const auto E : Exprs) {
+    if (isa<MemberExpr>(E)) {
+      if (isDependentMember(E))
+        return true;
+    } else if (E->isTypeDependent())
       return true;
+  }
 
   return false;
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D40566.124588.patch
Type: text/x-patch
Size: 2633 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171128/bcf94922/attachment-0001.bin>


More information about the cfe-commits mailing list