]> granicus.if.org Git - clang/commitdiff
Merging r196852:
authorBill Wendling <isanbard@gmail.com>
Tue, 10 Dec 2013 06:41:28 +0000 (06:41 +0000)
committerBill Wendling <isanbard@gmail.com>
Tue, 10 Dec 2013 06:41:28 +0000 (06:41 +0000)
------------------------------------------------------------------------
r196852 | majnemer | 2013-12-09 16:40:58 -0800 (Mon, 09 Dec 2013) | 10 lines

Sema: Enforce C++11 pointer-to-member template arguments should rules

The standard is pretty clear on what it allows inside of template
arguments for non-type template parameters of pointer-to-member.

They must be of the form &qualified-id and cannot come from sources like
constexpr VarDecls or things of that nature.

This fixes PR18192.

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_34@196885 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplate.cpp
test/SemaTemplate/instantiate-member-pointers.cpp

index 56eedc97a9bfcd863111e02f621781e45872b200..950edba46dd4d50b6126ab03d10392f479f1803a 100644 (file)
@@ -4588,9 +4588,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,
   else if ((DRE = dyn_cast<DeclRefExpr>(Arg))) {
     if (ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl())) {
       if (VD->getType()->isMemberPointerType()) {
-        if (isa<NonTypeTemplateParmDecl>(VD) ||
-            (isa<VarDecl>(VD) &&
-             S.Context.getCanonicalType(VD->getType()).isConstQualified())) {
+        if (isa<NonTypeTemplateParmDecl>(VD)) {
           if (Arg->isTypeDependent() || Arg->isValueDependent()) {
             Converted = TemplateArgument(Arg);
           } else {
index 0db90e3cbf120d9a73a37dbf14ed8b451537d29f..4757870d13b7081bf9cf327c7efe57422e6e3367 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 struct Y {
   int x;
 };
@@ -65,3 +65,10 @@ namespace ValueDepMemberPointer {
   }
   S<int> s; 
 }
+
+namespace PR18192 {
+  struct A { struct { int n; }; };
+  template<int A::*> struct X {};
+  constexpr int A::*p = &A::n;
+  X<p> x; // expected-error{{not a pointer to member constant}}
+}