From 0fc2a68848affd7bc99691400e5c1a85c1d11654 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Mon, 14 Apr 2014 16:44:26 +0000 Subject: [PATCH] Properly diagnose Microsoft __declspec attributes which have optional argument lists when the arguments are elided. eg) __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 | 15 +++++++++++++-- test/Parser/MicrosoftExtensions.c | 6 ++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 720a68c5ba..3fa3031ad0 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -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; } diff --git a/test/Parser/MicrosoftExtensions.c b/test/Parser/MicrosoftExtensions.c index b9f531fb1e..1998703e3d 100644 --- a/test/Parser/MicrosoftExtensions.c +++ b/test/Parser/MicrosoftExtensions.c @@ -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 {}; -- 2.40.0