]> granicus.if.org Git - clang/commitdiff
Properly diagnose Microsoft __declspec attributes which have optional argument lists...
authorAaron Ballman <aaron@aaronballman.com>
Mon, 14 Apr 2014 16:44:26 +0000 (16:44 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Mon, 14 Apr 2014 16:44:26 +0000 (16:44 +0000)
__declspec(deprecated()) // error
__declspec(deprecated) // OK
__declspec(deprecated("")) // OK

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

lib/Parse/ParseDecl.cpp
test/Parser/MicrosoftExtensions.c

index 720a68c5ba135bf3a7a3f53c614ea95e276a8075..3fa3031ad06f4775ddc23f059d9f6ae7c3c79dcd 100644 (file)
@@ -394,6 +394,8 @@ bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
     return false;
   }
 
+  SourceLocation OpenParenLoc = Tok.getLocation();
+
   if (AttrName->getName() == "property") {
     // The property declspec is more complex in that it can take one or two
     // assignment expressions as a parameter, but the lhs of the assignment
@@ -507,8 +509,17 @@ bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
     return !HasInvalidAccessor;
   }
 
-  ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, nullptr, nullptr,
-                           SourceLocation(), AttributeList::AS_Declspec);
+  unsigned NumArgs =
+      ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, nullptr, nullptr,
+                               SourceLocation(), AttributeList::AS_Declspec);
+
+  // If this attribute's args were parsed, and it was expected to have
+  // arguments but none were provided, emit a diagnostic.
+  const AttributeList *Attr = Attrs.getList();
+  if (Attr && Attr->getMaxArgs() && !NumArgs) {
+    Diag(OpenParenLoc, diag::err_attribute_requires_arguements) << AttrName;
+    return false;
+  }
   return true;
 }
 
index b9f531fb1e59aaebc98c6f5718c81423c08c6817..1998703e3d934b171fefd8599888af65686e7e16 100644 (file)
@@ -102,6 +102,12 @@ struct __declspec(frobble) S1 {};  /* expected-warning {{__declspec attribute 'fr
 struct __declspec(12) S2 {};   /* expected-error {{__declspec attributes must be an identifier or string literal}} */
 struct __declspec("testing") S3 {}; /* expected-warning {{__declspec attribute '"testing"' is not supported}} */
 
+/* declspecs with arguments cannot have an empty argument list, even if the
+   arguments are optional. */
+__declspec(deprecated()) void dep_func_test(void); /* expected-error {{attribute 'deprecated' requires a nonempty argument list}} */
+__declspec(deprecated) void dep_func_test2(void);
+__declspec(deprecated("")) void dep_func_test3(void);
+
 /* Ensure multiple declspec attributes are supported */
 struct __declspec(align(8) deprecated) S4 {};