r213650 - Disallowing GNU-style attributes in new expressions, since they are prohibited by GCC as well.
Aaron Ballman
aaron at aaronballman.com
Tue Jul 22 05:44:22 PDT 2014
Author: aaronballman
Date: Tue Jul 22 07:44:22 2014
New Revision: 213650
URL: http://llvm.org/viewvc/llvm-project?rev=213650&view=rev
Log:
Disallowing GNU-style attributes in new expressions, since they are prohibited by GCC as well.
Added:
cfe/trunk/test/SemaCXX/attr-gnu.cpp
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseStmtAsm.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=213650&r1=213649&r2=213650&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Jul 22 07:44:22 2014
@@ -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);
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=213650&r1=213649&r2=213650&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Jul 22 07:44:22 2014
@@ -4373,20 +4373,18 @@ bool Parser::isConstructorDeclarator(boo
/// 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(D
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(D
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(Dec
// 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(Dec
// 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(Decl
// 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.
Modified: cfe/trunk/lib/Parse/ParseStmtAsm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmtAsm.cpp?rev=213650&r1=213649&r2=213650&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmtAsm.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmtAsm.cpp Tue Jul 22 07:44:22 2014
@@ -590,7 +590,7 @@ StmtResult Parser::ParseAsmStatement(boo
}
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)
Added: cfe/trunk/test/SemaCXX/attr-gnu.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-gnu.cpp?rev=213650&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-gnu.cpp (added)
+++ cfe/trunk/test/SemaCXX/attr-gnu.cpp Tue Jul 22 07:44:22 2014
@@ -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++}}
More information about the cfe-commits
mailing list