Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 150127)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -1000,6 +1000,9 @@
                                      bool &AddToScope);
   bool AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
 
+  // Returns true if the type has illegal qualifiers and emits a diagnostic
+  bool CheckInvalidMemberQualifiers(SourceLocation Loc, QualType Pointer);
+
   /// \brief The kind of constexpr declaration checking we are performing.
   ///
   /// The kind affects which diagnostics (if any) are emitted if the function
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp	(revision 150128)
+++ lib/Sema/SemaDecl.cpp	(working copy)
@@ -4222,6 +4222,26 @@
   CheckShadow(S, D, R);
 }
 
+bool Sema::CheckInvalidMemberQualifiers(SourceLocation Loc, QualType Pointer) {
+  QualType Pointee;
+  unsigned PtrOrRef = 0;
+  if (const PointerType *Ptr = Pointer->getAs<PointerType>())
+    Pointee = Ptr->getPointeeType();
+  else if (const ReferenceType *Ref = Pointer->getAs<ReferenceType>()) {
+    Pointee = Ref->getPointeeType();
+    PtrOrRef = 1;
+  }      
+
+  if (!Pointee.isNull() && Pointee->isFunctionProtoType() &&
+      Pointee->getAs<FunctionProtoType>()->getTypeQuals() != 0) {
+    Diag(Loc, diag::err_invalid_qualified_function_pointer)
+        << PtrOrRef;
+    return true;
+  }
+  return false;
+}
+
+
 /// \brief Perform semantic checking on a newly-created variable
 /// declaration.
 ///
@@ -4343,18 +4363,7 @@
 
   // Function pointers and references cannot have qualified function type, only
   // function pointer-to-members can do that.
-  QualType Pointee;
-  unsigned PtrOrRef = 0;
-  if (const PointerType *Ptr = T->getAs<PointerType>())
-    Pointee = Ptr->getPointeeType();
-  else if (const ReferenceType *Ref = T->getAs<ReferenceType>()) {
-    Pointee = Ref->getPointeeType();
-    PtrOrRef = 1;
-  }
-  if (!Pointee.isNull() && Pointee->isFunctionProtoType() &&
-      Pointee->getAs<FunctionProtoType>()->getTypeQuals() != 0) {
-    Diag(NewVD->getLocation(), diag::err_invalid_qualified_function_pointer)
-        << PtrOrRef;
+  if (CheckInvalidMemberQualifiers(NewVD->getLocation(), T)) {
     NewVD->setInvalidDecl();
     return false;
   }
@@ -9237,6 +9246,24 @@
       FD->setInvalidDecl();
       EnclosingDecl->setInvalidDecl();
       continue;
+    } else if (FDTy->isPointerType() ||
+                FDTy->isReferenceType()) {
+      // As per [dcl.fct]p6:
+      //
+      //  A cv-qualifier-seq or a ref-qualifier shall only be part of:
+      //    - the function type for a non-static member function,
+      //    - the function type to which a pointer to member refers,
+      //    - the top-level function type of a function typedef declaration or 
+      //        alias-declaration,
+      //    - the type-id in the default argument of a type-parameter, or
+      //    - the type-id of a template-argument for a type-parameter.
+      //
+      // This means that a function pointer field cannot be cv-qualified.
+      if (CheckInvalidMemberQualifiers(FD->getLocation(), FD->getType())) {
+        FD->setInvalidDecl(true);
+        EnclosingDecl->setInvalidDecl(true);
+        continue;
+      }
     } else if (FDTy->isIncompleteArrayType() && Record && 
                ((i + 1 == Fields.end() && !Record->isUnion()) ||
                 ((getLangOptions().MicrosoftExt ||
@@ -9356,6 +9383,7 @@
         }
       }
     }
+
     // Keep track of the number of named members.
     if (FD->getIdentifier())
       ++NumNamedMembers;
Index: test/SemaCXX/illegal-member-qualifiers.cpp
===================================================================
--- test/SemaCXX/illegal-member-qualifiers.cpp	(revision 0)
+++ test/SemaCXX/illegal-member-qualifiers.cpp	(working copy)
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct test
+{
+	void (*ref)() const;  // expected-error {{type qualifier is not allowed on this function pointer}}
+	void (&ref2)() const; // expected-error {{type qualifier is not allowed on this function reference}}
+	void (*ref3)();
+};
+
+class test2 {
+  void (*ref)() const;  // expected-error {{type qualifier is not allowed on this function pointer}}
+};
Index: test/SemaCXX/illegal-member-qualifiers.cpp
===================================================================
--- test/SemaCXX/illegal-member-qualifiers.cpp	(revision 0)
+++ test/SemaCXX/illegal-member-qualifiers.cpp	(working copy)

Property changes on: test/SemaCXX/illegal-member-qualifiers.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
