Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 181511)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -1977,7 +1977,7 @@
   "variables, functions and labels|fields and global variables|structs|"
   "variables, functions and tag types|thread-local variables|"
   "variables and fields|variables, data members and tag types|"
-  "types and namespaces}1">;
+  "types and namespaces|function definitions}1">;
 def warn_function_attribute_wrong_type : Warning<
   "'%0' only applies to function types; type here is %1">,
   InGroup<IgnoredAttributes>;
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 181511)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -2426,7 +2426,8 @@
   void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL,
                                 bool NonInheritable = true,
                                 bool Inheritable = true,
-                                bool IncludeCXX11Attributes = true);
+                                bool IncludeCXX11Attributes = true,
+                                const Declarator *PD = 0);
   bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
                                       const AttributeList *AttrList);
 
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp	(revision 181511)
+++ lib/Sema/SemaDeclAttr.cpp	(working copy)
@@ -52,7 +52,8 @@
   ExpectedTLSVar,
   ExpectedVariableOrField,
   ExpectedVariableFieldOrTag,
-  ExpectedTypeOrNamespace
+  ExpectedTypeOrNamespace,
+  ExpectedFunctionDefinition
 };
 
 //===----------------------------------------------------------------------===//
@@ -1603,12 +1604,28 @@
                                        Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr,
+                            const Declarator *PD) {
   // Check the attribute arguments.
   if (!checkAttributeNumArgs(S, Attr, 0))
     return;
 
-  if (!isa<FunctionDecl>(D)) {
+  // Microsoft mode expects the naked attribute to only be applied to a
+  // function definition, or else it causes an error.  In non-Microsoft mode,
+  // the attribute is allowed to be attached to a function definition or is
+  // otherwise warned about.  This only applies to __declspec attributes, and
+  // not __attribute__ attributes.
+  //
+  // Because the attribute is handled before the function body is parsed, try
+  // to use the Declarator to determine whether this is a function definition
+  // or not.
+  bool IsFunctionDecl = isa<FunctionDecl>(D);
+  if (S.LangOpts.MicrosoftMode && Attr.isDeclspecAttribute() && 
+      (!IsFunctionDecl || (PD && !PD->isFunctionDefinition()))) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunctionDefinition;
+    return;
+  } else if (!IsFunctionDecl) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
       << Attr.getName() << ExpectedFunction;
     return;
@@ -4699,7 +4716,8 @@
 }
 
 static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
-                                       const AttributeList &Attr) {
+                                       const AttributeList &Attr,
+                                       const Declarator *PD) {
   switch (Attr.getKind()) {
   case AttributeList::AT_IBAction:    handleIBAction(S, D, Attr); break;
   case AttributeList::AT_IBOutlet:    handleIBOutlet(S, D, Attr); break;
@@ -4766,7 +4784,8 @@
       handleOwnershipAttr     (S, D, Attr); break;
   case AttributeList::AT_Cold:        handleColdAttr        (S, D, Attr); break;
   case AttributeList::AT_Hot:         handleHotAttr         (S, D, Attr); break;
-  case AttributeList::AT_Naked:       handleNakedAttr       (S, D, Attr); break;
+  case AttributeList::AT_Naked:       
+      handleNakedAttr       (S, D, Attr, PD); break;
   case AttributeList::AT_NoReturn:    handleNoReturnAttr    (S, D, Attr); break;
   case AttributeList::AT_NoThrow:     handleNothrowAttr     (S, D, Attr); break;
   case AttributeList::AT_CUDAShared:  handleSharedAttr      (S, D, Attr); break;
@@ -5000,7 +5019,8 @@
 static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
                                  const AttributeList &Attr,
                                  bool NonInheritable, bool Inheritable,
-                                 bool IncludeCXX11Attributes) {
+                                 bool IncludeCXX11Attributes,
+                                 const Declarator *PD) {
   if (Attr.isInvalid())
     return;
 
@@ -5013,7 +5033,7 @@
     ProcessNonInheritableDeclAttr(S, scope, D, Attr);
 
   if (Inheritable)
-    ProcessInheritableDeclAttr(S, scope, D, Attr);
+    ProcessInheritableDeclAttr(S, scope, D, Attr, PD);
 }
 
 /// ProcessDeclAttributeList - Apply all the decl attributes in the specified
@@ -5021,10 +5041,11 @@
 void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
                                     const AttributeList *AttrList,
                                     bool NonInheritable, bool Inheritable,
-                                    bool IncludeCXX11Attributes) {
+                                    bool IncludeCXX11Attributes,
+                                    const Declarator *PD) {
   for (const AttributeList* l = AttrList; l; l = l->getNext())
     ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable,
-                         IncludeCXX11Attributes);
+                         IncludeCXX11Attributes, PD);
 
   // GCC accepts
   // static int a9 __attribute__((weakref));
@@ -5186,7 +5207,8 @@
                                  bool NonInheritable, bool Inheritable) {
   // Apply decl attributes from the DeclSpec if present.
   if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
-    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
+    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable, 
+                             /*IncludeCXX11Attributes=*/true, &PD);
 
   // Walk the declarator structure, applying decl attributes that were in a type
   // position to the decl itself.  This handles cases like:
@@ -5195,11 +5217,12 @@
   for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
     if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
       ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable,
-                               /*IncludeCXX11Attributes=*/false);
+                               /*IncludeCXX11Attributes=*/false, &PD);
 
   // Finally, apply any attributes on the decl itself.
   if (const AttributeList *Attrs = PD.getAttributes())
-    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
+    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable,
+                             /*IncludeCXX11Attributes=*/true, &PD);
 }
 
 /// Is the given declaration allowed to use a forbidden type?
Index: test/Sema/MicrosoftCompatibility.c
===================================================================
--- test/Sema/MicrosoftCompatibility.c	(revision 181511)
+++ test/Sema/MicrosoftCompatibility.c	(working copy)
@@ -19,3 +19,9 @@
 struct __declspec(aligned) S2 {}; /* expected-warning {{unknown __declspec attribute 'aligned' ignored}} */
 
 struct __declspec(appdomain) S3 {}; /* expected-warning {{__declspec attribute 'appdomain' is not supported}} */
+
+__declspec(naked) int i; /* expected-error{{'naked' attribute only applies to function definitions}} */
+__declspec(naked) int func(void); /* expected-error{{'naked' attribute only applies to function definitions}} */
+
+/* This should work in MS compatibility mode */
+void t1() __attribute__((naked));
