From: David Majnemer Date: Tue, 25 Aug 2015 16:44:38 +0000 (+0000) Subject: [Sema] Handle leading and trailing __ for GNU attributes X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f4d02c776c0ac1cbdeeb2c56fc75d71d9f744103;p=clang [Sema] Handle leading and trailing __ for GNU attributes GNU attributes can have a leading and trailing __ appended/prepended to the attribute name. While the parser and AttributeList::getKind did the right thing, AttributeList::getAttributeSpellingListIndex did not. This fixes PR24565. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@245953 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp index 1ea40606f4..3c61c95ad8 100644 --- a/lib/Sema/AttributeList.cpp +++ b/lib/Sema/AttributeList.cpp @@ -109,6 +109,19 @@ void AttributePool::takePool(AttributeList *pool) { #include "clang/Sema/AttrParsedAttrKinds.inc" +static StringRef normalizeAttrName(StringRef AttrName, StringRef ScopeName, + AttributeList::Syntax SyntaxUsed) { + // Normalize the attribute name, __foo__ becomes foo. This is only allowable + // for GNU attributes. + bool IsGNU = SyntaxUsed == AttributeList::AS_GNU || + (SyntaxUsed == AttributeList::AS_CXX11 && ScopeName == "gnu"); + if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") && + AttrName.endswith("__")) + AttrName = AttrName.slice(2, AttrName.size() - 2); + + return AttrName; +} + AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name, const IdentifierInfo *ScopeName, Syntax SyntaxUsed) { @@ -118,13 +131,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name, if (ScopeName) FullName += ScopeName->getName(); - // Normalize the attribute name, __foo__ becomes foo. This is only allowable - // for GNU attributes. - bool IsGNU = SyntaxUsed == AS_GNU || (SyntaxUsed == AS_CXX11 && - FullName == "gnu"); - if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") && - AttrName.endswith("__")) - AttrName = AttrName.slice(2, AttrName.size() - 2); + AttrName = normalizeAttrName(AttrName, FullName, SyntaxUsed); // Ensure that in the case of C++11 attributes, we look for '::foo' if it is // unscoped. @@ -138,8 +145,9 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name, unsigned AttributeList::getAttributeSpellingListIndex() const { // Both variables will be used in tablegen generated // attribute spell list index matching code. - StringRef Name = AttrName->getName(); StringRef Scope = ScopeName ? ScopeName->getName() : ""; + StringRef Name = normalizeAttrName(AttrName->getName(), Scope, + (AttributeList::Syntax)SyntaxUsed); #include "clang/Sema/AttrSpellingListIndex.inc" diff --git a/test/SemaCXX/attr-print.cpp b/test/SemaCXX/attr-print.cpp index 337a6fb69b..f40d803e94 100644 --- a/test/SemaCXX/attr-print.cpp +++ b/test/SemaCXX/attr-print.cpp @@ -26,6 +26,9 @@ int small __attribute__((mode(byte))); // CHECK: int v __attribute__((visibility("hidden"))); int v __attribute__((visibility("hidden"))); +// CHECK: char *PR24565() __attribute__((malloc)) +char *PR24565() __attribute__((__malloc__)); + // CHECK: class __attribute__((consumable("unknown"))) AttrTester1 class __attribute__((consumable(unknown))) AttrTester1 { // CHECK: void callableWhen() __attribute__((callable_when("unconsumed", "consumed")));