Disallowing GNU-style attributes in new expressions, since they are prohibited by GCC as well.
llvm-svn: 213650
This commit is contained in:
parent
f2b96e3009
commit
08b065909f
|
@ -2207,8 +2207,21 @@ private:
|
|||
void ParseDeclaratorInternal(Declarator &D,
|
||||
DirectDeclParseFunction DirectDeclParser);
|
||||
|
||||
void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = true,
|
||||
bool CXX11AttributesAllowed = true,
|
||||
enum AttrRequirements {
|
||||
AR_NoAttributesParsed = 0, ///< No attributes are diagnosed.
|
||||
AR_GNUAttributesParsedAndRejected = 1 << 0, ///< Diagnose GNU attributes.
|
||||
AR_GNUAttributesParsed = 1 << 1,
|
||||
AR_CXX11AttributesParsed = 1 << 2,
|
||||
AR_DeclspecAttributesParsed = 1 << 3,
|
||||
AR_AllAttributesParsed = AR_GNUAttributesParsed |
|
||||
AR_CXX11AttributesParsed |
|
||||
AR_DeclspecAttributesParsed,
|
||||
AR_VendorAttributesParsed = AR_GNUAttributesParsed |
|
||||
AR_DeclspecAttributesParsed
|
||||
};
|
||||
|
||||
void ParseTypeQualifierListOpt(DeclSpec &DS,
|
||||
unsigned AttrReqs = AR_AllAttributesParsed,
|
||||
bool AtomicAllowed = true,
|
||||
bool IdentifierRequired = false);
|
||||
void ParseDirectDeclarator(Declarator &D);
|
||||
|
|
|
@ -4373,20 +4373,18 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified) {
|
|||
/// type-qualifier-list: [C99 6.7.5]
|
||||
/// type-qualifier
|
||||
/// [vendor] attributes
|
||||
/// [ only if VendorAttributesAllowed=true ]
|
||||
/// [ only if AttrReqs & AR_VendorAttributesParsed ]
|
||||
/// type-qualifier-list type-qualifier
|
||||
/// [vendor] type-qualifier-list attributes
|
||||
/// [ only if VendorAttributesAllowed=true ]
|
||||
/// [ only if AttrReqs & AR_VendorAttributesParsed ]
|
||||
/// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq
|
||||
/// [ only if CXX11AttributesAllowed=true ]
|
||||
/// Note: vendor can be GNU, MS, etc.
|
||||
///
|
||||
void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
|
||||
bool VendorAttributesAllowed,
|
||||
bool CXX11AttributesAllowed,
|
||||
/// [ only if AttReqs & AR_CXX11AttributesParsed ]
|
||||
/// Note: vendor can be GNU, MS, etc and can be explicitly controlled via
|
||||
/// AttrRequirements bitmask values.
|
||||
void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, unsigned AttrReqs,
|
||||
bool AtomicAllowed,
|
||||
bool IdentifierRequired) {
|
||||
if (getLangOpts().CPlusPlus11 && CXX11AttributesAllowed &&
|
||||
if (getLangOpts().CPlusPlus11 && (AttrReqs & AR_CXX11AttributesParsed) &&
|
||||
isCXX11AttributeSpecifier()) {
|
||||
ParsedAttributesWithRange attrs(AttrFactory);
|
||||
ParseCXX11Attributes(attrs);
|
||||
|
@ -4439,7 +4437,7 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
|
|||
case tok::kw___uptr:
|
||||
// GNU libc headers in C mode use '__uptr' as an identifer which conflicts
|
||||
// with the MS modifier keyword.
|
||||
if (VendorAttributesAllowed && !getLangOpts().CPlusPlus &&
|
||||
if ((AttrReqs & AR_DeclspecAttributesParsed) && !getLangOpts().CPlusPlus &&
|
||||
IdentifierRequired && DS.isEmpty() && NextToken().is(tok::semi)) {
|
||||
if (TryKeywordIdentFallback(false))
|
||||
continue;
|
||||
|
@ -4453,19 +4451,26 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
|
|||
case tok::kw___fastcall:
|
||||
case tok::kw___thiscall:
|
||||
case tok::kw___unaligned:
|
||||
if (VendorAttributesAllowed) {
|
||||
if (AttrReqs & AR_DeclspecAttributesParsed) {
|
||||
ParseMicrosoftTypeAttributes(DS.getAttributes());
|
||||
continue;
|
||||
}
|
||||
goto DoneWithTypeQuals;
|
||||
case tok::kw___pascal:
|
||||
if (VendorAttributesAllowed) {
|
||||
if (AttrReqs & AR_VendorAttributesParsed) {
|
||||
ParseBorlandTypeAttributes(DS.getAttributes());
|
||||
continue;
|
||||
}
|
||||
goto DoneWithTypeQuals;
|
||||
case tok::kw___attribute:
|
||||
if (VendorAttributesAllowed) {
|
||||
if (AttrReqs & AR_GNUAttributesParsedAndRejected)
|
||||
// When GNU attributes are expressly forbidden, diagnose their usage.
|
||||
Diag(Tok, diag::err_attributes_not_allowed);
|
||||
|
||||
// Parse the attributes even if they are rejected to ensure that error
|
||||
// recovery is graceful.
|
||||
if (AttrReqs & AR_GNUAttributesParsed ||
|
||||
AttrReqs & AR_GNUAttributesParsedAndRejected) {
|
||||
ParseGNUAttributes(DS.getAttributes());
|
||||
continue; // do *not* consume the next token!
|
||||
}
|
||||
|
@ -4601,8 +4606,13 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
|
|||
// Is a pointer.
|
||||
DeclSpec DS(AttrFactory);
|
||||
|
||||
// FIXME: GNU attributes are not allowed here in a new-type-id.
|
||||
ParseTypeQualifierListOpt(DS, true, true, true, !D.mayOmitIdentifier());
|
||||
// GNU attributes are not allowed here in a new-type-id, but Declspec and
|
||||
// C++11 attributes are allowed.
|
||||
unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
|
||||
((D.getContext() != Declarator::CXXNewContext)
|
||||
? AR_GNUAttributesParsed
|
||||
: AR_GNUAttributesParsedAndRejected);
|
||||
ParseTypeQualifierListOpt(DS, Reqs, true, !D.mayOmitIdentifier());
|
||||
D.ExtendWithDeclSpec(DS);
|
||||
|
||||
// Recursively parse the declarator.
|
||||
|
@ -5149,8 +5159,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
|
|||
// with the virt-specifier-seq and pure-specifier in the same way.
|
||||
|
||||
// Parse cv-qualifier-seq[opt].
|
||||
ParseTypeQualifierListOpt(DS, /*VendorAttributesAllowed*/ false,
|
||||
/*CXX11AttributesAllowed*/ false,
|
||||
ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed,
|
||||
/*AtomicAllowed*/ false);
|
||||
if (!DS.getSourceRange().getEnd().isInvalid()) {
|
||||
EndLoc = DS.getSourceRange().getEnd();
|
||||
|
@ -5546,7 +5555,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
|||
// If there is a type-qualifier-list, read it now.
|
||||
// Type qualifiers in an array subscript are a C99 feature.
|
||||
DeclSpec DS(AttrFactory);
|
||||
ParseTypeQualifierListOpt(DS, false /*no attributes*/);
|
||||
ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
|
||||
|
||||
// If we haven't already read 'static', check to see if there is one after the
|
||||
// type-qualifier-list.
|
||||
|
|
|
@ -590,7 +590,7 @@ StmtResult Parser::ParseAsmStatement(bool &msAsm) {
|
|||
}
|
||||
DeclSpec DS(AttrFactory);
|
||||
SourceLocation Loc = Tok.getLocation();
|
||||
ParseTypeQualifierListOpt(DS, true, false);
|
||||
ParseTypeQualifierListOpt(DS, AR_VendorAttributesParsed);
|
||||
|
||||
// GNU asms accept, but warn, about type-qualifiers other than volatile.
|
||||
if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// RUN: %clang_cc1 -std=gnu++11 -fsyntax-only -fms-compatibility -verify %s
|
||||
|
||||
void f() {
|
||||
// GNU-style attributes are prohibited in this position.
|
||||
auto P = new int * __attribute__((vector_size(8))); // expected-error {{an attribute list cannot appear here}} \
|
||||
// expected-error {{invalid vector element type 'int *'}}
|
||||
|
||||
// Ensure that MS type attribute keywords are still supported in this
|
||||
// position.
|
||||
auto P2 = new int * __sptr; // Ok
|
||||
}
|
||||
|
||||
void g(int a[static [[]] 5]); // expected-error {{static array size is a C99 feature, not permitted in C++}}
|
Loading…
Reference in New Issue