err_attribute_not_string has been subsumed by err_attribute_argument_type.

llvm-svn: 187400
This commit is contained in:
Aaron Ballman 2013-07-30 01:31:03 +00:00
parent 0cf702fa61
commit 3bf758cd65
12 changed files with 76 additions and 72 deletions

View File

@ -1790,6 +1790,9 @@ def err_alignas_underaligned : Error<
def err_attribute_argument_n_type : Error<
"%0 attribute requires parameter %1 to be %select{int or bool|an integer "
"constant|a string|an identifier}2">;
def err_attribute_argument_type : Error<
"%0 attribute requires %select{int or bool|an integer "
"constant|a string|an identifier}1">;
def err_attribute_argument_outof_range : Error<
"init_priority attribute requires integer constant between "
"101 and 65535 inclusive">;
@ -1854,8 +1857,6 @@ def err_field_with_address_space : Error<
"field may not be qualified with an address space">;
def err_attr_objc_ownership_redundant : Error<
"the type %0 is already explicitly ownership-qualified">;
def err_attribute_not_string : Error<
"argument to %0 attribute was not a string literal">;
def err_undeclared_nsnumber : Error<
"NSNumber must be available to use Objective-C literals">;
def err_invalid_nsnumber_type : Error<

View File

@ -798,6 +798,15 @@ private:
AttributeList *list;
};
/// These constants match the enumerated choices of
/// err_attribute_argument_n_type and err_attribute_argument_type.
enum AttributeArgumentNType {
AANT_ArgumentIntOrBool,
AANT_ArgumentIntegerConstant,
AANT_ArgumentString,
AANT_ArgumentIdentifier
};
} // end namespace clang
#endif

View File

@ -56,15 +56,6 @@ enum AttributeDeclKind {
ExpectedObjectiveCInterface
};
/// These constants match the enumerated choices of
/// err_attribute_argument_n_type.
enum AttributeArgumentNType {
ArgumentIntOrBool,
ArgumentIntegerConstant,
ArgumentString,
ArgumentIdentifier
};
//===----------------------------------------------------------------------===//
// Helper functions
//===----------------------------------------------------------------------===//
@ -266,7 +257,7 @@ static bool checkFunctionOrMethodArgumentIndex(Sema &S, const Decl *D,
!IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) {
std::string Name = std::string("'") + AttrName.str() + std::string("'");
S.Diag(AttrLoc, diag::err_attribute_argument_n_type) << Name.c_str()
<< AttrArgNum << ArgumentIntegerConstant << IdxExpr->getSourceRange();
<< AttrArgNum << AANT_ArgumentIntegerConstant << IdxExpr->getSourceRange();
return false;
}
@ -846,7 +837,7 @@ static bool checkTryLockFunAttrCommon(Sema &S, Decl *D,
if (!isIntOrBool(Attr.getArg(0))) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 1 << ArgumentIntOrBool;
<< Attr.getName() << 1 << AANT_ArgumentIntOrBool;
return false;
}
@ -1273,7 +1264,7 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
if (!AL.getParameterName()) {
S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
<< AL.getName()->getName() << 1 << ArgumentString;
<< AL.getName()->getName() << 1 << AANT_ArgumentString;
return;
}
// Figure out our Kind, and check arguments while we're at it.
@ -1456,7 +1447,7 @@ static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (!Str || !Str->isAscii()) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 1 << ArgumentString;
<< Attr.getName() << 1 << AANT_ArgumentString;
return;
}
// GCC will accept anything as the argument of weakref. Should we
@ -1480,8 +1471,8 @@ static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
if (!Str || !Str->isAscii()) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 1 << ArgumentString;
S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
<< Attr.getName() << AANT_ArgumentString;
return;
}
@ -1603,7 +1594,8 @@ static void handleTLSModelAttr(Sema &S, Decl *D,
// Check that it is a string.
if (!Str) {
S.Diag(Attr.getLoc(), diag::err_attribute_not_string) << "tls_model";
S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
<< Attr.getName() << AANT_ArgumentString;
return;
}
@ -1917,7 +1909,7 @@ static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (E->isTypeDependent() || E->isValueDependent() ||
!E->isIntegerConstantExpr(Idx, S.Context)) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 1 << ArgumentIntegerConstant
<< Attr.getName() << 1 << AANT_ArgumentIntegerConstant
<< E->getSourceRange();
return;
}
@ -1949,7 +1941,7 @@ static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (E->isTypeDependent() || E->isValueDependent() ||
!E->isIntegerConstantExpr(Idx, S.Context)) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 1 << ArgumentIntegerConstant
<< Attr.getName() << 1 << AANT_ArgumentIntegerConstant
<< E->getSourceRange();
return;
}
@ -1981,8 +1973,8 @@ static void handleAttrWithMessage(Sema &S, Decl *D,
if (NumArgs == 1) {
StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
if (!SE) {
S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
<< Attr.getName();
S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_argument_type)
<< Attr.getName() << AANT_ArgumentString;
return;
}
Str = SE->getString();
@ -2311,8 +2303,8 @@ static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr,
StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
if (!Str || !Str->isAscii()) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 1 << ArgumentString;
S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
<< Attr.getName() << AANT_ArgumentString;
return;
}
@ -2364,7 +2356,7 @@ static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 1 << ArgumentString;
<< Attr.getName() << 1 << AANT_ArgumentString;
} else {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
<< Attr.getName() << 0;
@ -2472,7 +2464,7 @@ handleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (!Attr.getParameterName()) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 1 << ArgumentString;
<< Attr.getName() << 1 << AANT_ArgumentString;
return;
}
@ -2510,7 +2502,7 @@ static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (E->isTypeDependent() || E->isValueDependent() ||
!E->isIntegerConstantExpr(Idx, S.Context)) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 1 << ArgumentIntegerConstant
<< Attr.getName() << 1 << AANT_ArgumentIntegerConstant
<< E->getSourceRange();
return;
}
@ -2531,7 +2523,7 @@ static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (E->isTypeDependent() || E->isValueDependent() ||
!E->isIntegerConstantExpr(Idx, S.Context)) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 2 << ArgumentIntegerConstant
<< Attr.getName() << 2 << AANT_ArgumentIntegerConstant
<< E->getSourceRange();
return;
}
@ -2803,7 +2795,8 @@ static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Expr *ArgExpr = Attr.getArg(0);
StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
if (!SE) {
S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
S.Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type)
<< Attr.getName() << AANT_ArgumentString;
return;
}
@ -3101,7 +3094,7 @@ static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (!Attr.getParameterName()) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 1 << ArgumentString;
<< Attr.getName() << 1 << AANT_ArgumentString;
return;
}
@ -3147,7 +3140,7 @@ static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 2 << ArgumentIntegerConstant
<< Attr.getName() << 2 << AANT_ArgumentIntegerConstant
<< IdxExpr->getSourceRange();
return;
}
@ -3203,7 +3196,7 @@ static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 3 << ArgumentIntegerConstant
<< Attr.getName() << 3 << AANT_ArgumentIntegerConstant
<< FirstArgExpr->getSourceRange();
return;
}
@ -3321,7 +3314,8 @@ static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// Make sure that there is a string literal as the annotation's single
// argument.
if (!SE) {
S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
S.Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type)
<< Attr.getName() << AANT_ArgumentString;
return;
}
@ -4004,8 +3998,8 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
Expr *Arg = attr.getArg(0);
StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
if (!Str || !Str->isAscii()) {
Diag(attr.getLoc(), diag::err_attribute_argument_n_type)
<< attr.getName() << 1 << ArgumentString;
Diag(attr.getLoc(), diag::err_attribute_argument_type) << attr.getName()
<< AANT_ArgumentString;
attr.setInvalid();
return true;
}
@ -4121,7 +4115,7 @@ static void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
MaxThreadsExpr->isValueDependent() ||
!MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 1 << ArgumentIntegerConstant
<< Attr.getName() << 1 << AANT_ArgumentIntegerConstant
<< MaxThreadsExpr->getSourceRange();
return;
}
@ -4133,7 +4127,7 @@ static void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
MinBlocksExpr->isValueDependent() ||
!MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 2 << ArgumentIntegerConstant
<< Attr.getName() << 2 << AANT_ArgumentIntegerConstant
<< MinBlocksExpr->getSourceRange();
return;
}
@ -4154,7 +4148,7 @@ static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
StringRef AttrName = Attr.getName()->getName();
if (!Attr.getParameterName()) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << /* arg num = */ 1 << ArgumentIdentifier;
<< Attr.getName() << /* arg num = */ 1 << AANT_ArgumentIdentifier;
return;
}
@ -4205,7 +4199,7 @@ static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
IdentifierInfo *PointerKind = Attr.getParameterName();
if (!PointerKind) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 1 << ArgumentIdentifier;
<< Attr.getName() << 1 << AANT_ArgumentIdentifier;
return;
}
@ -4562,8 +4556,8 @@ static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Expr *Arg = Attr.getArg(0);
StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
if (!Str || !Str->isAscii()) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
<< Attr.getName() << 1 << ArgumentString;
S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
<< Attr.getName() << AANT_ArgumentString;
return;
}

View File

@ -3943,8 +3943,8 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state,
AttrLoc = S.getSourceManager().getImmediateExpansionRange(AttrLoc).first;
if (!attr.getParameterName()) {
S.Diag(AttrLoc, diag::err_attribute_argument_n_type)
<< attr.getName() << 1 << 2 /*string*/;
S.Diag(AttrLoc, diag::err_attribute_argument_type)
<< attr.getName() << AANT_ArgumentString;
attr.setInvalid();
return true;
}
@ -4079,8 +4079,8 @@ static bool handleObjCGCTypeAttr(TypeProcessingState &state,
// Check the attribute arguments.
if (!attr.getParameterName()) {
S.Diag(attr.getLoc(), diag::err_attribute_argument_n_type)
<< attr.getName() << 1 << 2 /*string*/;
S.Diag(attr.getLoc(), diag::err_attribute_argument_type)
<< attr.getName() << AANT_ArgumentString;
attr.setInvalid();
return true;
}

View File

@ -4,21 +4,21 @@
[repeatable][source_annotation_attribute( Parameter|ReturnValue )]
struct SA_Post{ SA_Post(); int attr; };
[returnvalue:SA_Post( attr=1)]
[returnvalue:SA_Post( attr=1)]
int foo1([SA_Post(attr=1)] void *param);
namespace {
[returnvalue:SA_Post(attr=1)]
[returnvalue:SA_Post(attr=1)]
int foo2([SA_Post(attr=1)] void *param);
}
class T {
[returnvalue:SA_Post(attr=1)]
[returnvalue:SA_Post(attr=1)]
int foo3([SA_Post(attr=1)] void *param);
};
extern "C" {
[returnvalue:SA_Post(attr=1)]
[returnvalue:SA_Post(attr=1)]
int foo5([SA_Post(attr=1)] void *param);
}
@ -32,7 +32,7 @@ public:
void uuidof_test1()
{
{
__uuidof(0); // expected-error {{you need to include <guiddef.h> before using the '__uuidof' operator}}
}
@ -44,8 +44,8 @@ typedef struct _GUID
unsigned char Data4[8];
} GUID;
struct __declspec(uuid(L"00000000-0000-0000-1234-000000000047")) uuid_attr_bad1 { };// expected-error {{'uuid' attribute requires parameter 1 to be a string}}
struct __declspec(uuid(3)) uuid_attr_bad2 { };// expected-error {{'uuid' attribute requires parameter 1 to be a string}}
struct __declspec(uuid(L"00000000-0000-0000-1234-000000000047")) uuid_attr_bad1 { };// expected-error {{'uuid' attribute requires a string}}
struct __declspec(uuid(3)) uuid_attr_bad2 { };// expected-error {{'uuid' attribute requires a string}}
struct __declspec(uuid("0000000-0000-0000-1234-0000500000047")) uuid_attr_bad3 { };// expected-error {{uuid attribute contains a malformed GUID}}
struct __declspec(uuid("0000000-0000-0000-Z234-000000000047")) uuid_attr_bad4 { };// expected-error {{uuid attribute contains a malformed GUID}}
struct __declspec(uuid("000000000000-0000-1234-000000000047")) uuid_attr_bad5 { };// expected-error {{uuid attribute contains a malformed GUID}}
@ -59,7 +59,7 @@ struct struct_without_uuid { };
struct __declspec(uuid("000000A0-0000-0000-C000-000000000049"))
struct_with_uuid2;
struct
struct
struct_with_uuid2 {} ;
int uuid_sema_test()
@ -89,7 +89,7 @@ template <class T>
void template_uuid()
{
T expr;
__uuidof(T);
__uuidof(expr);
}
@ -113,7 +113,7 @@ typedef COM_CLASS_TEMPLATE_REF<struct_with_uuid, __uuidof(struct_with_uuid)> COM
struct __declspec(uuid("000000A0-0000-0000-C000-000000000049")) late_defined_uuid;
class CtorCall {
class CtorCall {
public:
CtorCall& operator=(const CtorCall& that);
@ -136,7 +136,7 @@ public:
class Iterator {
};
};
template<class T>
class C2 {
typename C1<T>:: /*template*/ Iterator<0> Mypos; // expected-warning {{use 'template' keyword to treat 'Iterator' as a dependent template name}}
@ -160,7 +160,7 @@ void redundant_typename() {
typename AAAA a;// expected-warning {{expected a qualified name after 'typename'}}
t = 3;
typedef typename T* pointerT;// expected-warning {{expected a qualified name after 'typename'}}
typedef typename SimpleTemplate<int> templateT;// expected-warning {{expected a qualified name after 'typename'}}
@ -239,25 +239,25 @@ __if_not_exists(IF_EXISTS::Type_not) {
int __if_exists_init_list() {
int array1[] = {
0,
0,
__if_exists(IF_EXISTS::Type) {2, }
3
};
int array2[] = {
0,
0,
__if_exists(IF_EXISTS::Type_not) { this wont compile }
3
};
int array3[] = {
0,
0,
__if_not_exists(IF_EXISTS::Type_not) {2, }
3
};
int array4[] = {
0,
0,
__if_not_exists(IF_EXISTS::Type) { this wont compile }
3
};
@ -300,7 +300,7 @@ class inline_definition_pure_spec {
int main () {
// Necessary to force instantiation in -fdelayed-template-parsing mode.
test_late_defined_uuid<int>();
test_late_defined_uuid<int>();
redundant_typename<int>();
missing_template_keyword<int>();
}

View File

@ -96,7 +96,7 @@ struct __declspec(deprecated) DS1 { int i; float f; }; // expected-note {{declar
#define MY_TEXT "This is also deprecated"
__declspec(deprecated(MY_TEXT)) void Dfunc1( void ) {} // expected-note {{'Dfunc1' declared here}}
struct __declspec(deprecated(123)) DS2 {}; // expected-error {{argument to 'deprecated' attribute was not a string literal}}
struct __declspec(deprecated(123)) DS2 {}; // expected-error {{'deprecated' attribute requires a string}}
void test( void ) {
e1 = one; // expected-warning {{'e1' is deprecated: This is deprecated}}

View File

@ -2,7 +2,7 @@
void __attribute__((annotate("foo"))) foo(float *a) {
__attribute__((annotate("bar"))) int x;
__attribute__((annotate(1))) int y; // expected-error {{argument to annotate attribute was not a string literal}}
__attribute__((annotate(1))) int y; // expected-error {{'annotate' attribute requires a string}}
__attribute__((annotate("bar", 1))) int z; // expected-error {{'annotate' attribute takes one argument}}
int u = __builtin_annotation(z, (char*) 0); // expected-error {{second argument to __builtin_annotation must be a non-wide string constant}}
int v = __builtin_annotation(z, (char*) L"bar"); // expected-error {{second argument to __builtin_annotation must be a non-wide string constant}}

View File

@ -1,7 +1,7 @@
// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-apple-darwin9 %s
int x __attribute__((section(
42))); // expected-error {{argument to section attribute was not a string literal}}
42))); // expected-error {{'section' attribute requires a string}}
// rdar://4341926

View File

@ -10,5 +10,5 @@ int x __attribute((tls_model("global-dynamic"))); // expected-error {{'tls_model
static __thread int y __attribute((tls_model("global-dynamic"))); // no-warning
static __thread int y __attribute((tls_model("local", "dynamic"))); // expected-error {{'tls_model' attribute takes one argument}}
static __thread int y __attribute((tls_model(123))); // expected-error {{argument to tls_model attribute was not a string literal}}
static __thread int y __attribute((tls_model(123))); // expected-error {{'tls_model' attribute requires a string}}
static __thread int y __attribute((tls_model("foobar"))); // expected-error {{tls_model must be "global-dynamic", "local-dynamic", "initial-exec" or "local-exec"}}

View File

@ -6,7 +6,7 @@ double dfoo(double) __attribute__((__unavailable__("NO LONGER"))); // expected-
void bar() __attribute__((__unavailable__)); // expected-note {{explicitly marked unavailable}}
int quux(void) __attribute__((__unavailable__(12))); // expected-error {{argument to '__unavailable__' attribute was not a string literal}}
int quux(void) __attribute__((__unavailable__(12))); // expected-error {{'__unavailable__' attribute requires a string}}
#define ACCEPTABLE "Use something else"
int quux2(void) __attribute__((__unavailable__(ACCEPTABLE)));
@ -37,13 +37,13 @@ enum foo {
a = 1, // expected-note {{declared here}}
b __attribute__((deprecated())) = 2, // expected-note {{declared here}}
c = 3
}__attribute__((deprecated()));
}__attribute__((deprecated()));
enum fee { // expected-note {{declaration has been explicitly marked unavailable here}}
r = 1, // expected-note {{declaration has been explicitly marked unavailable here}}
s = 2,
t = 3
}__attribute__((unavailable()));
}__attribute__((unavailable()));
enum fee f() { // expected-error {{'fee' is unavailable}}
int i = a; // expected-warning {{'a' is deprecated}}

View File

@ -39,7 +39,7 @@ Handler H = foo;
int __attribute__((pcs("aapcs", "aapcs"))) pcs1(void); // expected-error {{'pcs' attribute takes one argument}}
int __attribute__((pcs())) pcs2(void); // expected-error {{'pcs' attribute takes one argument}}
int __attribute__((pcs(pcs1))) pcs3(void); // expected-error {{'pcs' attribute takes one argument}}
int __attribute__((pcs(0))) pcs4(void); // expected-error {{'pcs' attribute requires parameter 1 to be a string}}
int __attribute__((pcs(0))) pcs4(void); // expected-error {{'pcs' attribute requires a string}}
/* These are ignored because the target is i386 and not ARM */
int __attribute__((pcs("aapcs"))) pcs5(void); // expected-warning {{calling convention 'pcs' ignored for this target}}
int __attribute__((pcs("aapcs-vfp"))) pcs6(void); // expected-warning {{calling convention 'pcs' ignored for this target}}

View File

@ -2,8 +2,8 @@
static id __attribute((objc_gc(weak))) a;
static id __attribute((objc_gc(strong))) b;
static id __attribute((objc_gc())) c; // expected-error{{'objc_gc' attribute requires parameter 1 to be a string}}
static id __attribute((objc_gc(123))) d; // expected-error{{'objc_gc' attribute requires parameter 1 to be a string}}
static id __attribute((objc_gc())) c; // expected-error{{'objc_gc' attribute requires a string}}
static id __attribute((objc_gc(123))) d; // expected-error{{'objc_gc' attribute requires a string}}
static id __attribute((objc_gc(foo, 456))) e; // expected-error{{'objc_gc' attribute takes one argument}}
static id __attribute((objc_gc(hello))) f; // expected-warning{{'objc_gc' attribute argument not supported: 'hello'}}