From a94e7b6acf15afbac93181f49cf23b9a3cea3df5 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Tue, 25 Aug 2015 16:44:38 +0000 Subject: [PATCH] [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. llvm-svn: 245953 --- clang/lib/Sema/AttributeList.cpp | 24 ++++++++++++++++-------- clang/test/SemaCXX/attr-print.cpp | 3 +++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/clang/lib/Sema/AttributeList.cpp b/clang/lib/Sema/AttributeList.cpp index 1ea40606f44b..3c61c95ad8ec 100644 --- a/clang/lib/Sema/AttributeList.cpp +++ b/clang/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/clang/test/SemaCXX/attr-print.cpp b/clang/test/SemaCXX/attr-print.cpp index 337a6fb69ba3..f40d803e94cb 100644 --- a/clang/test/SemaCXX/attr-print.cpp +++ b/clang/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")));